Z
O T in <T> is a place of the type that it will represent for a certain variable within a class. It is used in the statement of classes and their methods. Example:class MeuGenerico<T> { //T abreviacao de tipo
private T var;
public MeuGenerico() { }
public MeuGenerico(T var) { this.var = var; }
public T getVar() { return var; }
public void setVar(T var) { this.var = var; }
}
public class Teste {
public static void main(String[] args) {
MeuGenerico<Integer> mg = new MeuGenerico<>(42);
System.out.println(mg.getVar());
}
}
Output:42It is used when you want to create a class where your variables are of a type that is not defined at the time when it is written, but at the time it is used, leaving at the user's discretion that class will be the type of variable in place of the T.Beyond T that is an abbreviation for the "type", there are other acronyms standardized by convention among developers Java:And - ElementK - KeyN - NumberT - TypeV - ValueExample: http://docs.oracle.com/javase/7/docs/api/java/util/Map.html However, these acronyms they are special characters reserved by the compiler, you can use other characters you prefer, such as f, J, Z, or even whole words, such as meuTipo or $$. The rule that governs on what can go inside <> is the same that defines how the names of the variables can be, so your word cannot start with numbers and in no way can be a ?, as well as can not be a @ not even one #, among several other special characters that are also not allowed.Despite having this freedom to write whatever you want to be place, always try to follow the convention, because this facilitates communication between the developers.More details in: https://pt.stackoverflow.com/tags/gen%C3%A9ricos/info and also this https://docs.oracle.com/javase/tutorial/java/generics/types.html Already ?, in the context of generics, basically serves as a wildcardbecause he represents "any kind." Its function is to allow the use of polymorphism along with generics.When followed by the reserved word super, for example <? super Number> it accepts that any object whose supertype is Number is read or written to a variable, as it is safe to treat as Number any subtype of it. For example:import java.math.BigInteger;
class MeuGenerico<T> { //T abreviacao de tipo
private T var;
public MeuGenerico() { }
public T getVar() { return var; }
public void setVar(T var) { this.var = var; }
}
public class Teste {
public static void main(String[] args) {
MeuGenerico<? super Number> mg = new MeuGenerico<>();
//escrevendo em uma variável
mg.setVar(new Integer(1)); //válido
mg.setVar(new Float(2.0f)); //válido
mg.setVar(new BigInteger("99999999999999")); //válido
//mg.setVar(new String("999999999")); //inválido!!
}
}
It is worth remembering the hierarchy:java.lang. Object
java.lang. Number
java.util.concurrent.atomic. AtomicIntegerjava.util.concurrent.atomic. AtomicLongjava.math.BigDecimaljava.math. BigIntegerjava.lang.java.lang.Double.java.lang.Floatjava.lang. Integerjava.lang.Longjava.lang.Therefore, only the objects of the Number classes and their subtypes can be associated with the variable of our generic class.When followed by the reserved word extends, for example <? extends Number>, again it will only accept objects that are Number subtype, however this time it will not allow to write to the variables. Example:public class Teste {
public static void main(String[] args) {
MeuGenerico<? extends Number> mg = new MeuGenerico<>();
//tentando escrever em uma variável
//mg.setVar(new Integer(1)); //inválido!!
//mg.setVar(new Float(2.0f)); //inválido!!
//mg.setVar(new BigInteger("99999999999999")); //inválido!!
//mg.setVar(new String("999999999")); //inválido!!
}
}
At that time you may be wondering "How to read something of this variable if you cannot write anything in it?" .It is simple So: As its use is to allow the reading of the contents of the variables but without allowing to write in them, this statement is used when a parameter of a method is required for it to be passed as argument a variable with data already written in it. It is basically to allow the use of polymorphic methods to the same as generics. Example:import java.math.BigInteger;
class MeuGenerico<T> { //T abreviacao de tipo
private T var;
public MeuGenerico() { }
public T getVar() { return var; }
public void setVar(T var) { this.var = var; }
}
public class Teste {
public static void main(String[] args) {
MeuGenerico<Number> mg = new MeuGenerico<>();
mg.setVar(new Float(9.0f));
fazAlgoImportante(mg); //passa o argumento
mg.setVar(new BigInteger("999"));
fazAlgoImportante(mg); //passa o argumento
}
public static void fazAlgoImportante(MeuGenerico<? extends Number> mg) {
//nesse momento mg tem permissão apenas de leitura
System.out.println(mg.getVar().intValue() * mg.getVar().intValue()); //OK
//mg.setVar(new Float(9.0f)); //inválido!!
}
}
The argument received by the method fazAlgoImportante() will be treated as an object of the MyGeneric class, being the type used in place of T as if it were a Number. At that time, the guy who will take the place of T may be any subclass of Number, but regardless of whether it is an Integer, AtomicLong or BigInteger, only the methods provided by https://docs.oracle.com/javase/7/docs/api/java/lang/Number.html can be accessed, as is the expected behavior according to what is known of polymorphism.More details about the use of polymorphism and generics https://pt.stackoverflow.com/q/8679/3117 .Already <?> would be identical to do <? extends Object>.It is worth remembering that <? extends Object> is not the same thing <Object>, because in the first case you cannot write in the variable.ConclusionAs we can see, the place and wildcard have distinct characteristics and under no circumstances can be interchanged. Therefore, answering your question of what is the difference between the two is: ALL! Since in common only the fact that they are used with generics, there is nothing else.