views:

326

answers:

3

As I understand them, generics are a compile time feature of Java, and parametrized type information does not exist in the compiled byte code. I have now discovered the Field#getGenericType and Method#getGenericReturnType methods, thusly shattering my world view. Please help me to piece it together.

+2  A: 

When you're dealing with a jar of compiled bytecode in your IDE, you can still get generic auto-completion. This is how it's implemented. Basically you're right: types aren't completely erased.

cletus
+1  A: 

The just runtime types of objects are erased. For instance:

Object obj = new ArrayList<String>();

obj.getClass() will return ArrayList.class. You can even tell that ArrayList has a generic parameter. But there is no way to tell if obj was created as ArrayList<String>, ArrayList<Integer>, ArrayList<Object>, ArrayList (raw), or anything else.

Static type information is still there for class, methods, etc (although not for locals). This is just an extra bit of data appended as attributes in the class file, and available at runtime. Think of it much the same as annotations with runtime retention. Was there a question?

Tom Hawtin - tackline
+1  A: 

Static generic type information for fields and methods must be present in the compiled class file, so that when you compile other source code against it, the compiler can do type checking. For example, when you write code that uses a variable of type ArrayList<E>, and call a get() method on it, you don't have the source code for the ArrayList class. The compiler goes and looks at the compiled class file and gets the generic return type of the get() method, and realizes that it returns the generic type E, so that it can do type checking. Thus the generic type information must be present in order that the compiler can check it.

newacct