Skip to content

4.2 Use the diamond for type inference

Weverton edited this page Apr 6, 2017 · 9 revisions

O que é type inference?

É a capacidade do compilador Java examinar cada invocação de método e declaração correspondente para determinar o argumento de tipo (ou argumentos) que tornam a invocação aplicável.


Perceba que nesse cenário abaixo o T será substituido pela String e o X pela classe StringBuilder

class Parcel<T>{
   <X> Parcel(X x) {}
   public static void main(String[] args) {
      new Parcel<String>(new StringBuilder("Java"));
   }
}

Outro exemplo:

public class Teste13 {
    
    public static void main(String args[]) {
        Parcel<String> parcel = new Parcel<>(); // Instanciando de forma correta uma classe generica
        parcel.<Integer> deliver(new Integer(10)); // Especificando o Parametro generico de maneira correta
        // parcel.<>deliver(new Integer(10)); // Na chamada de metodo não e permitido fazer dessa maneira
        parcel.deliver("Hello"); // Outra chamada de metodo valida
    }
    
}

class Parcel<T> {
    
    public <X> void deliver(X x) {
        System.out.println(x.getClass());
    }

}


Uma exemplo de utilização de Bounded type

abstract class Gift {
    abstract double getWeight();
}

class Book extends Gift {
    public double getWeight() {
        return 3.2;
    }
}

class Phone extends Gift {
    public double getWeight() {
        return 1.1;
    }
}

/*
 * Dessa maneira você não tem acesso ao metodo getWeight()
 * 
class Parcel<T> {
    private T t;

    public void set(T t) {
        this.t = t;
    }

    public void shipParcel() {
        if (t.getWeight() > 10)
            System.out.println("Ship by courier ABC");
        else
            System.out.println("Ship by courier XYZ");
    }
}
*/

class Parcel<T extends Gift> { 
    private T t; // t pode ser qualquer filho de Gift

    public void set(T t) {
        this.t = t;
    }

    public void shipParcel() {
        double valor = t.getWeight(); 
        System.out.println(valor);
    }
}

Lembre que isso não compila:

class Parcel<T implements Serializable>{}

Multiplo Bounded:

public class Teste11 extends Gift implements Wrappable, Exchangeable {

    public static void main(String[] args) {      
        Parcel<Teste11> teste = new Parcel<>();    
    }

    @Override
    public void fazerE() {
    }

    @Override
    public void fazerW() {
    }
    
}

interface Wrappable{ 
    void fazerW();  
}

interface Exchangeable{   
    void fazerE(); 
}

class Gift {
    public void fazerG(){}
}

class Parcel <T extends Gift & Exchangeable & Wrappable>{
    
    T t;
    
    public void teste() {
        
        t.fazerW();
        t.fazerE();
        t.fazerG();
        
    }
    
}

Lembre:

Você não pode fazer isso: (String é final)

class MyClass extends String {}

Mas pode fazr isso:

metodo(List<? extends String> list)
Clone this wiki locally