volky
volky

Reputation: 198

Get method return type from an attribute of that methods parameter

I have a class C with an inner Class attribute:

public class C{
   private Class<?> clazz;

   public void setClazz(Class<?> c){
      this.clazz = c;
   }

   public Class<?> getClazz(){
      return clazz;
   }
}

and I want do declare a method in another class so it's return type is that of C.clazz :

public class D{
    public <T> T getInstance(C c){
       //doesn't compile
       //some reflective code to set T to c.getClazz?
       return (c.getClazz.newInstance());
    }
}  

so, for example, getInstance(c), with c having clazz set to Class<B>, would return me a new instance of B. Is there any way to do that with reflection?

Upvotes: 2

Views: 294

Answers (3)

Jatin
Jatin

Reputation: 31724

class C<T>{
    private final Class<T> clazz;

    C(Class<T> clazz) {
        this.clazz = clazz;
    }

    public Class<T> getClazz(){
        return clazz;
    }
}

class D{
    public <T> T getInstance(C<T> t) throws IllegalAccessException, InstantiationException {
        return t.getClazz().newInstance();
    }
}


public static void main() throws Exception {
    C<String> c = new C<>(String.class);
    D d = new D();
    String s = d.getInstance(c);
    System.out.println("String = " + s);
}

This is also a classic way of storing generic type information. But I dont understand on why you would want getInstace method inside D. I would rather make it a static method inside C.

You can adapt a similar tactic even it was an array with java.lang.reflect.Array.newInstance(t.getClazz(),10); rather than just t.getClazz().newInstance()

There are even other ways to capture generic type information. Read this for more complex stuff.

Upvotes: 5

Joop Eggen
Joop Eggen

Reputation: 109547

public class C<T> {
    private Class<T> clazz;

    public void setClazz(Class<T> c){
        this.clazz = c;
    }

    public Class<T> getClazz(){
        return clazz;
    }
}

public class D {
    public <T> T getInstance(C<T> c){
       //doesn't compile
       //some reflective code to set T to c.getClazz?
       return c.getClazz().newInstance();
    }
    public <T> T getInstance2(C c, Class<T> clazz){
       //doesn't compile
       //some reflective code to set T to c.getClazz?
       return clazz.cast(c.getClazz().newInstance());
    }
}

getInstance needs a C with T param, or else getInstance2 would need a Class as parameter, and do an unsafe cast (you could add a check).

Upvotes: 0

Glorfindel
Glorfindel

Reputation: 22641

You need getClazz() and a cast to T:

public class D {
    public <T> T getInstance(C c) throws InstantiationException, IllegalAccessException {
        return (T)(c.getClazz().newInstance());
    }
}

Upvotes: 0

Related Questions