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"