Java:如何从泛型类型中获取类文字? [英] Java: how do I get a class literal from a generic type?

查看:29
本文介绍了Java:如何从泛型类型中获取类文字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Typically, I've seen people use the class literal like this:

Class<Foo> cls = Foo.class;

但是如果类型是通用的,例如列表?这工作正常,但有一个警告,因为 List 应该被参数化:

But what if the type is generic, e.g. List? This works fine, but has a warning since List should be parameterized:

Class<List> cls = List.class

那么为什么不添加一个 呢?好吧,这会导致类型不匹配错误:

So why not add a <?>? Well, this causes a type mismatch error:

Class<List<?>> cls = List.class

我认为这样的事情会起作用,但这只是一个普通的语法错误:

I figured something like this would work, but this is just a plain ol' syntax error:

Class<List<Foo>> cls = List<Foo>.class

我怎样才能静态地获得一个 Class>,例如使用类字面量?

How can I get a Class<List<Foo>> statically, e.g. using the class literal?

可以使用@SuppressWarnings("unchecked")来消除第一个例子中非参数化使用List引起的警告,类<列表>cls = List.class,但我不想.

I could use @SuppressWarnings("unchecked") to get rid of the warnings caused by the non-parameterized use of List in the first example, Class<List> cls = List.class, but I'd rather not.

有什么建议吗?

推荐答案

由于 输入擦除.

Java 泛型只不过是对象强制转换的语法糖.演示:

Java generics are little more than syntactic sugar for Object casts. To demonstrate:

List<Integer> list1 = new ArrayList<Integer>();
List<String> list2 = (List<String>)list1;
list2.add("foo"); // perfectly legal

在运行时保留泛型类型信息的唯一实例是 Field.getGenericType() 如果通过反射询问类的成员.

The only instance where generic type information is retained at runtime is with Field.getGenericType() if interrogating a class's members via reflection.

这就是为什么 Object.getClass() 有这个签名:

All of this is why Object.getClass() has this signature:

public final native Class<?> getClass();

重要的部分是Class.

换句话说,来自 Java 泛型常见问题解答:

因为参数化类型没有精确的运行时类型表示.

一个类字面量表示一个 Class表示给定类型的对象.例如,类文字String.class 表示Class表示类型的对象String 与返回的 Class 对象方法 getClassString 对象.类文字可以用于运行时类型检查和用于反思.

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.

参数化类型丢失其类型当它们被翻译成的参数编译期间的字节码过程称为类型擦除.作为一个类型擦除的副作用,所有泛型类型共享的实例化相同的运行时表示,即相应的原始类型 .换句话说,参数化类型没有类型表示他们自己的.因此,有形成类文字没有意义比如 List.classList.classList.class,因为不存在这样的 Class 对象.只有原始类型 List 有一个 Class表示其运行时的对象类型.它被称为List.class.

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:如何从泛型类型中获取类文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆