Java将参数化泛型类型作为valueType发送
我有一个返回给定类型的方法:Java将参数化泛型类型作为valueType发送,java,generics,Java,Generics,我有一个返回给定类型的方法: T foo(Class<T> valueType) {...}; String s = foo(Java.lang.String.class); tfoo(Class-valueType){…}; strings=foo(Java.lang.String.class); 我试图发送泛型类型作为我的类,但遇到编译器错误。例如,假设我想返回字符串的ArrayList: ArrayList<String> list = foot(ArrayL
T foo(Class<T> valueType) {...};
String s = foo(Java.lang.String.class);
tfoo(Class-valueType){…};
strings=foo(Java.lang.String.class);
我试图发送泛型类型作为我的类,但遇到编译器错误。例如,假设我想返回字符串的ArrayList:
ArrayList<String> list = foot(ArrayList<String>.class)
ArrayList list=foot(ArrayList.class)
参数“String”给出错误。我是否可以指定要返回的泛型类型?运行时
类
字段值不取决于应用的泛型类型,此语法是非法的。更多信息。这对您有用吗(已编辑)
只需转换方法的输入或输出:
ArrayList<String> list = foot((Class<ArrayList<String>>)(Class<?>)ArrayList.class);
ArrayList list=foot((Class)(Class)ArrayList.Class);
或
ArrayList list=(ArrayList)foot(ArrayList.class);
基本上,类
类不能很好地处理泛型,因为它代表运行时,而泛型在编译时工作。在运行时,程序中只有一个类对象用于ArrayList
。即使你称它为Class
或Class
或Class
,它仍然是同一个对象。那么它应该是什么类型的呢?没有一个简单的答案适用于一切
Java语言决定类literal
ArrayList.class
应该只有类型class
。但是,当您需要类型为Class
的表达式时,这会导致问题,因此您必须弯曲类型。假设您在这里只关心静态类型,此技巧可能很有用:
@SuppressWarnings("unchecked")
public static <T>
Class<T> appropriateClass(T... args) {
return (Class<T>) args.getClass().getComponentType();
}
Class<ArrayList<String>> c = appropriateClass();
ArrayList<String> list = foo(c);
因此,它相当于一个丑陋的类型转换,如(Class)(Class)ArrayList.Class
如果您在运行时确实需要为
ArrayList
和ArrayList
使用不同的令牌,那么您应该使用肖恩·帕特里克·弗洛伊德(Sean Patrick Floyd)提到的TypeToken
技术。类型擦除技术会让人大吃一惊。本质上,Java对泛型
子句进行编译时检查,然后从运行时对象中删除它们,从而永远丢失信息。讨厌,嗯?由于.class
元对象在运行时被引用,因此它们也会受到擦除的影响
ArrayList.class
在编译时被擦除,成为ArrayList.class
若希望泛型具有类型安全性,则必须传入两个参数,例如
ArrayList foo=foot(ArrayList.class,String.class)
可能ArrayList list=foot(ArrayList.class)
?这会编译,但我想返回一个参数化对象。然后使用包装器可能是个好主意。将参数化对象传递给包装器,然后将包装的类传递给实际方法。这样行吗?
ArrayList<String> list = (ArrayList<String>)foot(ArrayList.class);
@SuppressWarnings("unchecked")
public static <T>
Class<T> appropriateClass(T... args) {
return (Class<T>) args.getClass().getComponentType();
}
Class<ArrayList<String>> c = appropriateClass();
ArrayList<String> list = foo(c);
System.out.println(c); // prints "class java.util.ArrayList"