Java:如何从泛型类型中获取类文字? [英] Java: how do I get a class literal from a generic type?
问题描述
通常,我见过人们像这样使用类文字:
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
对象方法 getClass
在String
对象.类文字可以用于运行时类型检查和用于反思.
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
,List
和 List>.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屋!