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 );
}
}