Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can I get .class from generic type argument?

I have the following class:

public abstract class MyClass<T extends Object> {

    protected T createNewFromData(Reader reader){
        GSON.fromJSON(reader,T.class); // T.class isn't allowed :(
    }
}

How do I pass a Class<T> instance into there? Is there some wierd and wacky work around?

Is there a way to get a Class<T> reference other than from a pre-instantiated Object of type T? It won't let me do this either:

T t = new T();
Class<T> klass = t.class;

Attempt #2

Interestingly, if I remove the "extends JSONOBjBase" from the class definition, I simply get an unchecked cast WARNING (no error). Is there another way to write how the cast is done?

eclipse screenshot

like image 816
Mike S Avatar asked Sep 21 '12 03:09

Mike S


People also ask

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.

How do you find the class type of a generic type?

To implement generics, the Java compiler applies type erasure to: Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.

Can we inherit generic class in Java?

Generics also provide type safety (ensuring that an operation is being performed on the right type of data before executing that operation). Hierarchical classifications are allowed by Inheritance. Superclass is a class that is inherited. The subclass is a class that does inherit.

How do you indicate that a class has a generic type parameter?

A generic type is declared by specifying a type parameter in an angle brackets after a type name, e.g. TypeName<T> where T is a type parameter.


2 Answers

No.
Due to type erasure, this information does not exist at runtime.

Instead, you can re-use GSON's TypeToken hack, which creates an anonymous class that inherits a closed generic base class.

like image 195
SLaks Avatar answered Sep 30 '22 06:09

SLaks


Or you can send the Class as a constructor argument and use that object instead of trying to get T.class.

public abstract class MyClass<T extends Object> {

    private Class<T> klass;

    public MyClass(Class<T> klass) {
        this.klass = klass;
    }

    protected T createNewFromData(Reader reader){
        GSON.fromJSON(reader,klass); 
    }
}
like image 44
Alex Calugarescu Avatar answered Sep 30 '22 05:09

Alex Calugarescu