I was surprised today when this code compiled:
class GenericClass<T> {
public void emptyMethod(T instance) {
// ..
}
public void print(T instance) {
System.out.println(instance);
}
}
public class Main {
public static void main(String[] args) {
GenericClass first = new GenericClass();
System.out.println("Wow");
first.emptyMethod(10);
first.print(16);
}
}
The compiler emits a warning (Type safety: The method emptyMethod(Object) belongs to the raw type GenericList. References to generic type GenericList should be parameterized), but anyway it does not cause a compiler error and it runs ‘fine’ (at least the provided print method). As I’m understanding, the compiler is using object as the type argument, but I find it counter-intuitive. Why would the compiler do such thing? Why it doesn’t require me to specify the type parameter?
You’re using a raw class, basically.
Think back to when generics were first introduced in Java: there was a load of code which already used
List,ArrayListetc. In order to avoid breaking all of that code, but still reusing the existing classes, raw types were introduced – it’s basically using a generic type as if it weren’t one.As you can see, you get a warning – so it’s worth avoiding – but that’s the primary reason for it being allowed at all.
See section 4.8 of the JLS for more information, which includes: