Generics in Java are purely a compile time construct to ensure type safety - they're erased by the compiler and replaced by the raw equivalent (but guaranteed safe unless you've specifically casted to void that type safety.)
This is a relatively neat way of implementing generics, since no modifications need to be done to the VM or hotspot - just the compiler. As well as the obvious limitation that there's no generic type information available at runtime, it does occasionally pose the limitation that the "generic-free" instance has to make sense also. For instance if I want to do something like:
public class CompareMe implements Comparator<Thing>, Comparator<OtherThing> {
public int compareTo(Thing other) {
//Blah
}
public int compareTo(OtherThing other) {
//Blah
}
}
...then that's not possible using that form, since the direct generic-free equivalent would be:
public class CompareMe implements Comparator, Comparator {
public int compareTo(Object other) {
//Blah
}
public int compareTo(Object other) {
//Blah
}
}
...and clearly there's an issue with clashing names there! Of course, this could be re-written using a single comparator, or using a compareTo method with a custom comparator passed in, but it's worth taking note of.