我有一个这样的清单:
private List<T> myList = new ArrayList<T>();
我想得到T.的.class我怎么能这样做?
我的意思是:
myList.getClass()
修改 我试过了:
Field genericField = Wrapper.class.getDeclaredField("myList");
ParameterizedType genericType = (ParameterizedType) genericField.getGenericType();
Class<?> genericClass = (Class<?>) genericType.getActualTypeArguments()[0];
当我调试它时
genericType
的值为:
的java.util.List
所以我认为这个问题肯定与此问题不同:Get generic type of java.util.List因为如果您使用T
声明了一个类,并在稍后的另一个方法中为T
分配了一些内容, T
暂时消失。
答案 0 :(得分:11)
你不能因为类型擦除。 泛型类型在运行时是未知的(它被'擦除'),它仅在编译时使用。
这是java泛型和c#泛型之间的主要区别。例如。
答案 1 :(得分:3)
为什么你需要知道这个?也许这会做你需要的事情
// must be at least one element (and all elements are the same)
Class elementType = myList.get(0).getClass();
要做到这一点的唯一方法是
像
private final Class<T> type;
private final List<T> list = new ArrayList<T>();
public Class<T> getType() { return type; }
像
List list = new ArrayList<Integer>() { }; // create a specific sub-class
final Class<? extends List> listClass = list.getClass();
final ParameterizedType genericSuperclass = (ParameterizedType) listClass.getGenericSuperclass();
Class elementType = (Class) genericSuperclass.getActualTypeArguments()[0];
这样做的一个缺点是,您最终可能会创建大量匿名类,并可能会对ArrayList.class != list.getClass()
之类的内容产生混淆,list instanceof ArrayList
答案 2 :(得分:1)
你做不到。该信息在运行时不可用。如果您的列表不为空,您可以通过检查第一个元素的类来逃避。
答案 3 :(得分:0)
只有当你的例子中暗示的列表是一个字段并且type参数是具体的而不是它本身是封闭类的类型参数(在你的例子中似乎是这种情况)时,这是唯一可能的。您只能通过反射获取字段的声明类型参数:
Field listField = Test.class.getDeclaredField("myList");
ParameterizedType listType= (ParameterizedType) listField.getGenericType();
Class contentClass = (Class) listType.getActualTypeArguments()[0];
不确定这是否完全正确,但你明白了 - 它相当复杂,因为类型参数可以是有界的和通配符。