Tuesday, December 05, 2006

Type Literals

Yesterday I wrote about super type tokens, which is an API that acts like class literals but with two advantages over class literals: they work with generic types, and they provide full generic type information. The disadvantages are that they are more verbose than class literals, and (being a different type than java.lang.Class) they are incompatible with APIs that use type tokens. It turns out that it is possible to get the best of both worlds by adding super type tokens to the language. I would call the resulting construct type literals.

The basic idea would be to retrofit java.lang.reflect.Type with generics, in the same way that java.lang.Class was retrofitted with generics in JDK5. Then the type of List<String>.class would be Type<List<String>>, and the structure of the resulting object would contain all of the generic type information that a Type is capable of expressing. The code generated by javac could very well use the trick outlined in my previous blog post, though I expect there are much more efficient ways of doing it. You would then be able to write

Type<List<String>> x = List<String>.class; 

The "type literal" on the right is currently a syntax error, but this language extension would give meaning to the syntax. How does this fit with the existing meaning of class literals? Very nicely. The type java.lang.Class already extends java.lang.reflect.Type, so a class literal of type Class<String> could be assigned to a variable of type Type<String>. In other words, the following would be legal:

Type<String> x = String.class;  

Adding support for type literals to the language and retrofitting java.lang.reflect.Type would simplify the use of the THC pattern with generic types and make existing type-token-based APIs interoperate nicely with the pattern.

2 comments:

Anonymous said...

In my opinion, this change must be done in coordination with a fix for bug
6184881
.

Else, the type of the type literal can be improved to
ParametrizedType<List<String>> x = List<String>.class.

And what about adding a method like newInstance ?

RĂ©mi

Unknown said...

Type is awkward to generify because interface TypeVariable<D extends GenericDeclaration> extends Type.

Adding newInstance to Type breaks the rule about adding methods to interfaces. Also the Type system is designed to be useable independently of Classes. (And Class.newInstance is purest evil.)

So perhaps introduce an abstract class between Type and Class.