通常,我见过人们像这样使用类文字:
Class<Foo> cls = Foo.class;
但是如果类型是通用的,例如列表?这工作正常,但有一个警告,因为列表应该参数化:
Class<List> cls = List.class
那么为什么不添加 <?>
?好吧,这会导致类型不匹配错误:
Class<List<?>> cls = List.class
我认为这样的东西会起作用,但这只是一个简单的语法错误:
Class<List<Foo>> cls = List<Foo>.class
如何获得 Class<List<Foo>>
静态地,例如使用类文字?
我可以使用@SuppressWarnings("unchecked")
消除第一个示例中因非参数化使用 List 而引起的警告,Class<List> cls = List.class
,但我不想。
有什么建议吗?
最佳答案
你不能因为 type erasure .
Java 泛型只不过是对象转换的语法糖。演示:
List<Integer> list1 = new ArrayList<Integer>();
List<String> list2 = (List<String>)list1;
list2.add("foo"); // perfectly legal
在运行时保留泛型类型信息的唯一实例是 Field.getGenericType()
如果通过反射询问类的成员。
这就是为什么 Object.getClass()
有这个签名:
public final native Class<?> getClass();
重要的部分是Class<?>
.
换句话说,来自 Java Generics FAQ :
Why is there no class literal for concrete parameterized types?
Because parameterized type has no exact runtime type representation.
A class literal denotes a
Class
object that represents a given type. For instance, the class literalString.class
denotes theClass
object that represents the typeString
and is identical to theClass
object that is returned when methodgetClass
is invoked on aString
object. A class literal can be used for runtime type checks and for reflection.Parameterized types lose their type arguments when they are translated to byte code during compilation in a process called type erasure . As a side effect of type erasure, all instantiations of a generic type share the same runtime representation, namely that of the corresponding raw type . In other words, parameterized types do not have type representation of their own. Consequently, there is no point in forming class literals such as
List<String>.class
,List<Long>.class
andList<?>.class
, since no suchClass
objects exist. Only the raw typeList
has aClass
object that represents its runtime type. It is referred to asList.class
.
关于Java:如何从泛型类型获取类文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56969182/