Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert from TypeReference<E> to Class<E> without casting (Java)

I want to go from a TypeReference<E> object to a Class<E> object in Java, without using casting. I require the usage of TypeReference because of the way my code uses Jackson and I need Class object because I want to use it to infer a type into one of my other Generic Classes in my app.

I know that TypeReference.getType() will return a java.lang.reflect.Type object. Basically, if I can find out a way to use code without casting to get from Type to Class, then I have figured out my problem.

Javadoc References:

  • http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html
  • http://jackson.codehaus.org/1.9.4/javadoc/org/codehaus/jackson/type/TypeReference.html
like image 567
ecbrodie Avatar asked Oct 31 '12 19:10

ecbrodie


People also ask

What is TypeReference in Java?

public class TypeReference extends Object. A reference to a type appearing in a class, field or method declaration, or on an instruction.

Do generics prevent type cast errors?

Implementing generics into your code can greatly improve its overall quality by preventing unprecedented runtime errors involving data types and typecasting.

What does class <?> Mean in Java?

What Does Class Mean? A class — in the context of Java — is a template used to create objects and to define object data types and methods. Classes are categories, and objects are items within each category. All class objects should have the basic class properties.

How do I get a class instance of generic type T?

The short answer is, that there is no way to find out the runtime type of generic type parameters in Java. A solution to this is to pass the Class of the type parameter into the constructor of the generic type, e.g.


2 Answers

You can not cast it: this is very basic Java question -- TypeReference and Class do not derive from same base class so it is against language definition.

But if I guess correctly what you trying to achieve, you can convert raw (type-erased) class by using JavaType:

JavaType type = mapper.getTypeFactory().constructType(ref);
Class<?> cls = type.getRawClass();

You can construct JavaType out of TypeReference, Class, or even just basic JDK Type.

like image 171
StaxMan Avatar answered Oct 30 '22 00:10

StaxMan


I don't see any solution without casting. However, here is a solution with kind of generic casting. Maybe this can help, too:

public class Converter {
    public static <T> Class<T> convert(TypeReference<T> ref) {
        return (Class<T>)((ParameterizedType) ref.getType()).getRawType();
    }
}

However this is a framework method. The signature is fully type save and it converts to a class containing all the 'super type token' information Neal Gafter mentions in his blog entry that's delivered the idea of TypeReference. By that it keeps your business code clean and type save.

Usage would then (Here you can't see the cast...;-):

Class<List<String>> typ = Converter.convert(new TypeReference<List<String>>() {});
System.out.println(typ);

With output (Of course the instance is type ereased even though the code shows the String...):

interface java.util.List
like image 45
Bernd Ebertz Avatar answered Oct 29 '22 22:10

Bernd Ebertz