By convention, T
is used to represent a type Parameter, or type parameter, used in declaring a generic class.
As already mentioned in Jean’s reply, there is a convention for more common cases, although you can use any letter in practice.
A classic example is the class statement List
, which represents a list of elements. Therefore we have:
public interface List<E> extends Collection<E> { ... }
When using the list, we can then define the type E
of the list, thus:
List<String> nomes = new ArrayList<>();
And now the compiler will let you know if we try to put anything other than a String
on the list.
Only sometimes we want to explicitly leave a list without a defined type. This could be done only with List
, but in that case the compiler will think you forgot to declare the type.
For that we use the wildcard ?
, as in the example:
int contar(List<?> qualquerTipo) {
return qualquerTipo.size();
}
Note that I don’t need to know the type to count the list elements, so it’s a perfectly valid use.
There are other applications for this, but it is usually a type of generic meta-programming used in frameworks or utility routines where the actual type doesn’t matter.
This should not be used often in the day-to-day implementations of systems we do, as it is far more insecure.