As said in this thread,
for Example List<Integer>
list.get (index).getClass()
will not give you type of object stored in list:
- when the list is empty
- even when the list is NOT empty, because any element can be any subclass of the generic type parameter.
Since type parameters are erased at compile time, they do not exist at runtime (sorry Jon, at execution time): Hence you cannot get generic type info via reflection in java.
There is a case for more reification which is on the table (Java 7 ?), and would facilitate what you are after.
One would hope that a bad type, casted into T, would provoke a Cast exception that would, at execution time, reveal the original type used for T, but alas, that does not work either.
Consider the following test class:
import java.util.ArrayList;
/**
* @param <T>
*/
public class StoreGerenericTypeInField<T>
{
private T myT = null;
private ArrayList<T> list = new ArrayList<T>();
private void setT(final T aT) { myT = aT; }
/**
* Attempt to do private strange initialization with T, in the hope to provoke a cast exception
*/
public StoreGerenericTypeInField()
{
StringBuilder aFirstType = new StringBuilder();
StringBuffer aSecondType = new StringBuffer();
this.list.add((T)aFirstType);
this.list.add((T)aSecondType);
System.out.println(this.list.get(0).getClass().getName());
System.out.println(this.list.get(1).getClass().getName());
setT((T)aFirstType);
System.out.println(this.myT.getClass().getName());
setT((T)aSecondType);
System.out.println(this.myT.getClass().getName());
}
/**
* @param args
*/
public static void main(String[] args)
{
StoreGerenericTypeInField<Integer> s = new StoreGerenericTypeInField<Integer>();
}
}
The constructor attempt to store nasty thing into its T variable (or its List of T)... and everything run smoothly!?
It prints:
java.lang.StringBuilder
java.lang.StringBuffer
java.lang.StringBuilder
java.lang.StringBuffer
The type erasure in in itself is not to blame... that is the combination of type erasure (new to java) and unsafe casting (java legacy old feature) which makes T truly out of reach at execution time (until you actually try to use it with 'T
' specific methods)