I got this one from a google I/O puzzler talk given by Joshua Bloch. Here\'s the code
public class Glommer {
String glom(Collection>
You can read more about Raw Types to understand it fully
Basically, raw types are for using legacy code, almost anything in a raw class will become raw itself, in this case those 2 methods.
So when it is raw there is a method that gets a List
and one for Collection
so its called the List
one, if its not raw, the methods are not raw also and it will call the Collection
one because it has the extra information
The called method is defined at compilation time, not at runtime.
If you add a parameter to your constructor call, the compiler will have enough information to know that it has to call the first method. Otherwise, it's just as if generics didn't exist. In both case, the called method will always stay the same at runtime.
EDIT Some people seem to doubt, so here's another example:
public class Test {
private static void test(Object object) {
System.out.println("Object method");
}
private static void test(Integer integer) {
System.out.println("Integer method");
}
public static void main(String[] args) {
Object object = Integer.valueOf(0);
test(object);
}
}
The result is:
Object method
You pass an Integer to your method, but all that the compiler knows at compile time is that it's an object. The jvm doesn't automagically change the method call even though the Object is actually an Integer.
This is because when new Glommer()
is called without generics the Generic<Type>()
, all of type matches are removed from the class.
As strings variable is a List
, if it does not have any generic <Type>
then it will match the glom(List ints)
. The type checking doesn't get done till later.
When we create new Glommer<AnyType>
the types are all left in place, so when we pass our strings
variable it does type checking. The compiler can now check if it is a List<Integer>
, which is not so it gets passed to the glom(Collection<?> obj)
method.
Hope this helps, please ask for any clarification if you need!