Generics are at once the most welcome, easy to understand and most perplexing feature added to Java since… well ever! I couldn’t imagine life without them, but like anything in type theory they are at times confoundingly opaque. Here are some all-too-common misconceptions about Java Generics and Generic types in general:
- Set<Child> is a subtype of Set<Parent>
This is an unfortunate misapprehension brought on by the rather strange fact that Child[] is a subtype of Parent[].
- Type erasure means there is no real difference between Set<T>, Set or Set<E>
Type erasure means there is no way to enforce the difference between them at runtime.
- Set<?> is equal to Set<?>
This one came up in the Guice list recently: why can’t we declare a variable as Set<?> and then bind it to some implementation that Set<?> accepts?
The answer is that Set<?> is a wildcard type. In other words, it is a query on all types that match Set<?>. Like Set<Object>, Set<Socket>, Set<BuckRogers>, and everything else besides.
Java cannot close over the scope of all possible bindings to any give Set<?>. In other words, because Set<?> can be any Set type, Java cannot assume that it is any one Set type. Therefore you cannot bind Set<?> to any particular Set.
- The same goes for Set<? extends Thing>
This is a special kind of wildcard known as a bounded wildcard. In essence, a wildcard is a closure over the global scope of the program. If such a closure were possible, we could bind wildcards correctly. But this is not doable without the source code to everything (aka global compilation =)
- Type reification would have let us do cool things like new T();
No, it would not.
- Guice can @Inject List<T> if I bind all possible List<T>’s used in my program
Type erasure means that Guice has no idea what the witness of T was, when bound.
Filed under: 1 | Leave a Comment
Tags: closures, generics, guice, java, type system, type theory
No Responses Yet to “Clearing up misconceptions about Generics”