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

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

问题描述

通常,我看到人们使用类字面量,如下所示:

 类< Foo> cls = Foo.class; 

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

 类< List& cls = List.class 

那么为什么不添加<?& ?这会导致类型不匹配错误:

 类< List<?& cls = List.class 

我想这样的东西会工作,但这只是一个简单的ol'语法错误:

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



如何获得 List< Foo>> 使用类文字?



我可以使用 @SuppressWarnings(unchecked)为了摆脱在第一个示例中非参数化使用List引起的警告, Class< List>



有任何建议吗?

解决方案

您不能因为 type erasure



Java泛型只是对象类型的语法糖。要演示:

 列表< Integer> list1 = new ArrayList< Integer>(); 
List< String> list2 =(List< String>)list1;
list2.add(foo); //完全合法

在运行时保留通用类型信息的唯一实例是 Field.getGenericType() p>

所有这些都是为什么 Object.getClass( ) 有此签名:

  public final native Class<?& getClass(); 

重要的是类<?>



换句话说,从 Java泛型常见问题


为什么没有具体参数化类型的类文字?



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



$ c> Class
表示给定类型的对象。
例如,类文字
String.class 表示
代表
String 类型的对象,它与返回的
对象相同当在
String 对象上调用
方法 getClass 类文字可以
用于运行时类型检查,
用于反射。



参数化类型在编译期间在
过程中被称为类型擦除时转换为
字节码时,将丢失其类型
参数。作为类型擦除的
副作用,类属类型的所有
实例化共享
相同的运行时表示,
是对应的原始
类型的。换句话说,参数化的
类型没有自己的类型表示
。因此,有
没有点形成类文字
例如 List< String> .class,
List< Long> .class List<?> .class
,因为没有这样的 / code>对象。
只有原始类型 List 有一个
表示其运行时的对象
型。它被称为
List.class



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

Class<Foo> cls = Foo.class;

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' a syntax error:

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

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

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.

Any suggestions?

解决方案

You can't due to type erasure.

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

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

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

public final native Class<?> getClass();

The important part being Class<?>.

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

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