Skip
Skip

Reputation: 6521

Java reflections generics - cast by passing a parameter at compile time?

There is a following situation:
A class is given, with a generic field in it. Is it possible to instantiate the field at runtime with an instance of T?

class Root<T>{
   T var;

   Root(){
     //instantiate var with an instance of T here
   }
}

Upvotes: 1

Views: 815

Answers (5)

Esko Luontola
Esko Luontola

Reputation: 73625

If you have a class which extends Root<T> and sets the type parameter in its extends clause, then it's possible to dig it out using getGenericSuperclass(). For example Guice uses this approach to provide type parameter information to the injected classes.

Otherwise, the best bet is to pass a Class<T> instance as constructor parameter and use it. This will also result in simpler code, though a bit more boilerplate for each instantiation of the class.

Upvotes: 4

Vivien Barousse
Vivien Barousse

Reputation: 20875

There is no way to know the type of T at runtime since it is erased at compile time.

However, you can add a new parameter to your constructor of type Class<T>. The compiler will ensure that the object passed is a Class instance corresponding to the T type you specified for your Root instance. In your constructor, you can then use reflection to create a new T instance:

class Root<T> {

    T var;

    public Root(Class<T> klass) {
        var = klass.newInstance();
    }

}

This supposes your T type has a default constructor.

Upvotes: 1

Andreas Holstenson
Andreas Holstenson

Reputation: 1428

No. If you really need this functionality you will need to pass in the type in your constructor.

Like this:

class Root<T> {
  private T var;

  public Root(Class<T> type) {
    var = type.newInstance();
  }
}

This will create an instance via reflection. It will only work if the class passed in has a default constructor. Otherwise you'll need to extend the example.

Upvotes: 0

takteek
takteek

Reputation: 7110

Unless you are given an instance of T at runtime, the answer is no because of java type erasure. At runtime T is actually replaced with Object so the necessary information doesn't exist. This is the reason that functions like List.toArray require you to pass in a typed array in order to receive a typed result.

Upvotes: 1

SLaks
SLaks

Reputation: 887433

No.

Java uses type erasure, so the generic parameter does not exist at runtime.

Upvotes: 2

Related Questions