简体   繁体   English

如何使用有效的泛型声明Class.class

[英]how to declare Class.class with valid generics

Note: purely out of curiosity and not for any actual use case. 注意:完全出于好奇而不是任何实际用例。

I'm wondering if there is a way to declare the Class Class object with valid type parameters: 我想知道是否有办法用有效的类型参数声明Class Class对象:

Class cc1 = Class.class; //raw type
Class<Class> cc2 = Class.class; //now parameter is raw type
Class<Class<?>> cc3 = Class.class; //compile error: inconvertible types

If Class and Class<?> are interchangeable, why are Class<Class> and Class<Class<?>> not? 如果ClassClass<?>是可以互换的,为什么Class<Class>Class<Class<?>>不是?

EDIT: the question can be generalized to an issue of nested raw type parameters. 编辑:该问题可以推广到嵌套原始类型参数的问题。 For example: 例如:

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList>(); //same compile error

EDIT2: I should rephrase the question a little: I know that EDIT2:我应该稍微改一下这个问题:我知道

Class<?> c = Class.class;

is valid but I'm wondering why Class<Class> is not the same as Class<Class<?>> 是有效的,但我想知道为什么Class<Class>Class<Class<?>>

It's kind of difficult to see exactly what you're asking (or what you're trying to do).. but you can parametrize without raw types. 很难确切地看到你在问什么(或者你想要做什么)..但是你可以在没有原始类型的情况下进行参数化。

Class<? extends Object> cc4 = Class.class; // no raw types
Class<?> cc5 = Class.class; // also an option

As far as your last example is concerned, it makes no sense because it appears you want to make an array list of array lists that hold ? 就你的上一个例子而言,没有任何意义,因为看起来你想要制作一个包含数组列表的数组列表? , but your declaration isn't declaring an array list of array lists that hold ? ,但你的声明没有声明一个数组列表的数组列表? .

Properly written (but still not proper Java) would be: 正确编写(但仍然不合适的Java)将是:

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList<Integer>>(); // Type mismatch

Which is expected. 这是预期的。 It doesn't work for the same reason something like the following doesn't work: 由于以下原因不起作用,它不起作用:

Object o = new Object();
Integer i = new Integer(3);

o = i;
i.floatValue();
o.floatValue(); // can't access that method, we need to specifically cast it to Integer

Java types aren't proactively inferred (even in an inheritance chain). 不主动推断Java类型(即使在继承链中)。

If you want to keep the wildcard in there, you're welcome to, though: 如果你想保留通配符,欢迎你,但是:

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList<?>>(); // works!

The rule here is that the generic type in the left side must match the generic type in the right side. 这里的规则是左侧的泛型类型必须与右侧的泛型类型匹配。

Class<?> means a class of any type. Class<?>表示任何类型的类。

Class<?> c = Class.class; 

Works because Class of any type can be Class<Class> . 因为任何类型的Class都可以是Class<Class>

Class<Class<?>> cc3 = Class.class;

Do not work because Class.class type is Class<Class> which is not of type Class<Class<?>> 不起作用,因为Class.class类型是Class<Class> ,它不是Class<Class<?>>

ArrayList<ArrayList<Integer>> lst = new ArrayList<ArrayList<Integer>>();
ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList<?>>();

Works because the two expressions match. 因为两个表达式匹配而起作用。

ArrayList<ArrayList<?>> lst = new ArrayList<ArrayList>();

Don't match. 不匹配。

Generics have some pretty serious limitations. 泛型有一些非常严重的限制。 In this case you can't assign a type to the inner type of Class<Class> because you're actually referencing the raw type, not an implementation of the raw type. 在这种情况下,您不能将类型分配给Class<Class>的内部类型,因为您实际上是引用原始类型,而不是原始类型的实现。 It will give you a warning, but you have no way to fix that warning. 它会给你一个警告,但是你无法修复那个警告。

Class<Class<?>> by itself isn't an inconvertible type, you just can't assign a class directly to it because it doesn't have the type Class<Class<T>> , it has the type Class<T> . Class<Class<?>>本身不是一个不可转换的类型,你只是不能直接为它分配一个类,因为它没有Class<Class<T>>类型,它的类型为Class<T>

Think of it another way; 以另一种方式思考; try List<List<String>> . 尝试List<List<String>> To create that, you need to create a List that takes a List of Strings. 要创建它,您需要创建一个带有字符串列表的List。 This works because lists can contain lists. 这有效,因为列表可以包含列表。

A Class is more like a primitive than a data object, so I don't think it'd be possible to create a Class that is of type Class of something else. Class更像是一个原语而不是一个数据对象,所以我认为不可能创建一个Class类型为Class的Class。

Edit : your extra question about ArrayList<ArrayList<?>> is a more obvious example of the inconvertible type issue you're having with Class<Class<?>> . 编辑 :关于ArrayList<ArrayList<?>>额外问题是您在Class<Class<?>>遇到的不可转换类型问题的一个更明显的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM