Java:如何从泛型类型获取类文字?

标签 java generics class literals

通常,我见过人们像这样使用类文字:

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 literal String.class denotes the Class object that represents the type String and is identical to the Class object that is returned when method getClass is invoked on a String 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 and List<?>.class , since no such Class objects exist. Only the raw type List has a Class object that represents its runtime type. It is referred to as List.class.

关于Java:如何从泛型类型获取类文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56969182/

相关文章:

java - 在 Hibernate 中获取表列名称

scala - 在 akka 消息中保留类型/类标签

java - 将未知泛型类型与 List 类一起使用

c++ - 为什么 C++ 析构函数会发生这种情况?

java - 抽象类中的私有(private)构造函数

Perl:散列键丢失了它们的类信息

java - SMPP 二进制消息

java - 无法使用 JSoup 获取页面的完整内容

java - Docker-从 tar 文件安装 Java 8 和 Tomcat 8

java - 在运行时确定泛型方法参数的类型