I'm reading the SCJP by mughal (3rd edition) (the best SCJP book i have come across) and on page 727, it says the following:
class My开发者_高级运维IntList extends ArrayList <Integer> {} // A reifiable subclass
Now i'm just a bit puzzled here. I do know the subclass is of a non-generic type but since it extends ArrayList <Integer> and the parameterized <Integer> will be erased eventually, and this subclass will inherit properties of it's superclass, why would this subclass MyIntList be a reifiable type?
Because every instance of MyIntList
is a Array<Integer>
, you can find out the lower/upper bounds using reflection.
If you said class MyNumberList<T extends Number> extends ArrayList<T> { ... }
, you can still find the bounds, but not exactly what T
was for a particular instance of MyNumberList
.
from The Java Language Specification http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html
4.7 Reifiable Types
Because some type information is erased during compilation, not all types are available at run time. Types that are completely available at run time are known as reifiable types. A type is reifiable if and only if one of the following holds:
- It refers to a non-generic type declaration.
- It is a parameterized type in which all type arguments are unbounded wildcards (§4.5.1).
- It is a raw type (§4.8).
- It is a primitive type (§4.2).
- It is an array type (§10.1) whose component type is reifiable.
The generic type is erased during compilation of ArrayList, but not during compilation of MyIntList. So during runtime you can find out that MyIntList extends ArrayList by calling MyIntList.class.getGenericSuperclass()
and analyzing the returned object.
The reason why this is possible is that MyIntList itself is not generic, but extends a concrete instantiation of ArrayList. So this information can just be stored in the Class object of MyIntList (from where it is accessible using the method mentioned above).
精彩评论