Super Type Tokens
Class<T> works fine so long as T is a raw type, but I recently needed to pass around references to full blown generic types. For example, due to the fact that Java uses erasure to maximize compatibility, List.class compiles but List<Integer>.class does not.
Ted recently ran into this problem, too. He was lucky enough to get off with a warning, but my code actually needs to differentiate between List<Integer> and List<String>.
Neal came to the rescue with a clever (and cleverly named) pattern for retaining otherwise non-reifiable types at runtime. Check out super type tokens.
In a nutshell, instead of saying List<Integer>.class, you can say new TypeReference<List<Integer>>() {}, where the API for TypeReference may look very similar to that of Class.
4 Comments:
Yea, that Gafter's Gadget is definitely a brilliant idea! By the way, what for you are developing the dependency injection framework?
Seems like a lot of reflection for little gain, why don't you do this instead:
interface Factory< T > { T newInstance(); }
...
Factory< List< String > > stringsFactory = new Factory< List< String > > {
public List< String > newInstance() { return new List< String >(); }
}
And on the naming front, what's wrong with Factory.
Eugene, just toying with some ideas. ;)
Anonymous, the newInstance() method was just a small example. Super type tokens go well beyond creating new instances of types.
The syntax may leave a little to be desired, but you can always add sugar. The semantics are what's important.
You should just use Haskell (which is where Java generics came from in the first place), in which case you'd have different types for [Integer] (the equivalent of List<Integer>) and [String] (the equivalent of List<String>).
Post a Comment
<< Home