Generics have been introduced into Java to help you catch a wide range of bugs in compile-time, instead of just encountering ClassCastException
at runtime.
When you use <?>
(a wildcard) you are saying to the compiler that you don't know (or don't care about) the generic type. For example: if you just want to count the number of elements of an Iterable<?>
, you simply don't care about the types of the elements, so you could create a method with the signature int countElements(Iterable<?> iterable)
, that would simply retrieve an Iterator<?>
from the iterable
(note the wildcard type again), and then just call hasNext()
and next()
, while incrementing a counter.
You could do the same without the <?>
, which is what is called a raw type.
You should almost never use raw types. Raw types are allowed since Java tries to be as backwards compatible as possible. If they didn't allow you to use raw types, almost all Java code from versions before 1.5 (when Generics have been introduced) would have to be rewritten; the raw types allows the compiler to compile that code -- although it will issue warnings.