Hi, I'd like to suggest the addition of a type token class to the Java class library, to be used for representing generic types such as List<String>.
Actual class literals can only represent raw types. But often libraries have the need to apply some sort of configuration to specific generic types, link specific behaviour to them or expose (meta) data related to them. The suggested type token class would allow to implement such cases in a type-safe fashion. # Example use cases * The "type-safe heterogenous container" pattern from Joshua Bloch's book "Effective Java" introduces a container which allows to safely store and retrieve objects of different types. They are keyed by Class<?>, which means that one cannot have a value for a List<String> and another value for a List<Integer> in such container. Also one cannot obtain a List<String> without casting from such container. Type literals would allow this: <T> void put(TypeLiteral<T> type, T value); <T> T get(TypeLiteral<T> type); TypeLiteral<List<String>> stringListType = ...; List<String> stringList = container.get( stringListType ); * JAX-RS allows to read response message entities into parameterized types using its GenericType class: List<Customer> customers = response.readEntity( new GenericType<List<Customer>>() {} ); * CDI allows to dynamically obtain beans of specific parameterized types using its TypeLiteral class: @Inject @Any Instance<PaymentProcessor> anyPaymentProcessor; public PaymentProcessor<Cheque> getChequePaymentProcessor() { PaymentProcessor<Cheque> pp = anyPaymentProcessor .select( new TypeLiteral<PaymentProcessor<Cheque>>() {} ).get(); } # Proposed solution Type literals would be represented by a new type java.lang.reflect.TypeLiteral<T>. Instances would be created via sub-classing, capturing the <T> parameter and baking it into the sub-class: TypeLiteral<List<String>> stringListType = new TypeLiteral<List<String>>(){}; That'd allow to provide type-safe APIs around generic types as shown in the examples above. The following methods should be defined on TypeLiteral in order to make it useful for implementers of such APIs: Type getType(); Class<?> getRawType(); boolean equals(Object obj); int hashCode(); String toString(); # Prior art The idea of type tokens based on capturing a generic type in a sub-class has been around for a long time. The first reference I've found is Neal Gafter's blog post on "Super Type Tokens" from 2006 [1]. Examples in real-world APIs and libraries are TypeLiteral<T> in CDI [2], GenericType<T> in JAX-RS [3], TypeLiteral<T> in commons-lang [4] and TypeToken<T> in Guava [5]. # Alternatives and shortcomings The obvious alternative would be reified generics, but I think it's commonly agreed upon that these will not come to the Java language any time soon. Without native support in the language itself the proposed type literal class is the best way to support the mentioned use cases as far as I can say. Shortcomings are the creation of a sub-class per literal instantiation (probably more an aesthetic problem, though) and failure of the pattern when type variables are included anywhere in the represented type [6]. Unfortunately, this can only be detected at runtime when instantiating a literal but not by the compiler (although, I reckon it technically could, by handling this case specifically). # Conclusion Lacking reified generics, the Java platform would benefit from the addition of new type token class java.lang.reflect.TypeLiteral. The pattern's presence in common APIs and libraries shows that there is a wide-spread need for such mechanism and the community would benefit very much from a standardized solution in the JDK itself. This will allow for more unified API designs as well as foster integration of different libraries. I'm eager to learn about your feedback and the OpenJDK team's assessment of this proposal. --Gunnar [1] http://gafter.blogspot.de/2006/12/super-type-tokens.html [2] https://docs.oracle.com/javaee/7/api/index.html?javax/enterprise/util/TypeLiteral.html [3] https://docs.oracle.com/javaee/7/api/index.html?javax/ws/rs/core/GenericType.html [4] https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/reflect/TypeLiteral.html [5] https://google.github.io/guava/releases/20.0/api/docs/index.html?com/google/common/reflect/TypeToken.html [6] http://gafter.blogspot.de/2007/05/limitation-of-super-type-tokens.html