I have a generics class, Foo. In a method of Foo, I want to get the class instance of type T, but I just can\'t call T.
There is a small loophole however: if you define your Foo class as abstract.
That would mean you have to instantiate you class as:
Foo myFoo = new Foo(){};
(Note the double braces at the end.)
Now you can retrieve the type of T at runtime:
Type mySuperclass = myFoo.getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
Note however that mySuperclass has to be the superclass of the class definition actually defining the final type for T.
It is also not very elegant, but you have to decide whether you prefer new Foo or new Foo in your code.
For example:
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.NoSuchElementException;
/**
* Captures and silently ignores stack exceptions upon popping.
*/
public abstract class SilentStack extends ArrayDeque {
public E pop() {
try {
return super.pop();
}
catch( NoSuchElementException nsee ) {
return create();
}
}
public E create() {
try {
Type sooper = getClass().getGenericSuperclass();
Type t = ((ParameterizedType)sooper).getActualTypeArguments()[ 0 ];
return (E)(Class.forName( t.toString() ).newInstance());
}
catch( Exception e ) {
return null;
}
}
}
Then:
public class Main {
// Note the braces...
private Deque stack = new SilentStack(){};
public static void main( String args[] ) {
// Returns a new instance of String.
String s = stack.pop();
System.out.printf( "s = '%s'\n", s );
}
}