1

I have a generic class

public MyObject<T extends SomeClass1, S extends SomeClass2> extends SomeExternalClass {
    // ....
    @override
    public void someFunction() {
        ExternalClass.doSomething(T.class); // problem here!
    }
}

Inside this class, I need an object of type Class<T> to pass it to a function of an external library. The external library expects an object of type Class<T extends SomeClass1>as parameter.

I read about a solution to pass a Class<T> into the constructor of my object. Unfortunately, MyObject extends a certain class, also from an external library, which has a certain constructor that will always be called - so this is no option for me.

I read about Guava, for example here: Get generic type of class at runtime The difference to my problem is that I need an Object of type Class<T> and not an object of type Type. How can I achieve this?

Thanks in advance!

Community
  • 1
  • 1
mario.schlipf
  • 1,187
  • 2
  • 12
  • 25
  • 1
    You can't. Generic types are erased at runtime, that is why some methods require `Class` instances to preserve information about type. – Pshemo Jul 08 '15 at 22:30
  • But what about Guava? I thought this would be one solution, but I cannot figure out how.. – mario.schlipf Jul 08 '15 at 22:31
  • Which Guava solution do you mean? If it is this one http://stackoverflow.com/a/19775924/1393766 then it doesn't work as author claims. You should test it yourself. – Pshemo Jul 08 '15 at 22:39
  • `TypeToken` as used in the duplicate will get you want you want. –  Jul 09 '15 at 00:07

1 Answers1

0

As mentioned by Pshemo in a comment you can't really do this in Java directly because of type erasure. However, a couple of ways to achieve that would be to take the class as a parameter of the someFunction. E.g.

public class MyObject<T extends SomeClass1, S extends SomeClass2> {
    // ....
    public void someFunction(Class<T> clazz) {
        ExternalClass.doSomething(clazz); // problem here!
    }
}

Then you would push the problem further out.

In case you have a field of type T that has an object of that type you could use that to pass to the ExternalClass, e.g.

public class MyObject<T extends SomeClass1, S extends SomeClass2> {
    private T t;
    public MyObject(T t) {
        this.t = t;
    }

    public void someFunction() {
        ExternalClass.doSomething(t.getClass()); // problem here!
    }
}

A third option if you can not alter the signature of neither the constructor nor the someFunction would be to maldate a call to a setter method that you control, e.g.

public class MyObject<T extends SomeClass1, S extends SomeClass2> {
    private T t;

    public void someFunction() {
        ExternalClass.doSomething(t.getClass()); // problem here!
    }

    public void setClazz(T t) {
        this.t = t;
    }
}

You could expand on this and let the caller register a callback that you use to resolve the class, but that might be overkill...

Emil H
  • 16,495
  • 3
  • 39
  • 62
  • Unfortunately, I cannot modify neither the constructor nor the function parameters, because they are overriding the parent methods. – mario.schlipf Jul 08 '15 at 22:42
  • @schlimpf then you could call another method in the class that lets you resolve the class. See my updated answer. However, there might be better ways to achieve what you want to do if you could wrap the `SomeExternalClass` instead of extending it... – Emil H Jul 08 '15 at 23:59