[英]Java generics: why someObject.getClass() doesn't return Class<? extends T>?
I would expect that from the aspect of compile time as well as from the aspect of runtime it wouldn't be a problem for .getClass()
to provide a correctly-typed return value. 我希望从编译时以及运行时的角度来看,
.getClass()
提供正确类型的返回值都不会成为问题。
But I must be wrong. 但是我一定是错的。
public class _GetClassGenerics2 {
static class MyClass {
}
public static void main(String[] args) {
MyClass myInstance = new MyClass();
// here it works
Class<? extends MyClass> type = myInstance.getClass();
myMethod(myInstance);
}
public static <T extends MyClass> void myMethod(T instance) {
Class<? extends T> type = instance.getClass();
// java.lang.RuntimeException: Uncompilable source code - incompatible types
// required: java.lang.Class<? extends T>
// found: java.lang.Class<capture#1 of ? extends _GetClassGenerics2.MyClass>
}
}
EDIT: It doesn't work with Class<T>
and Class<? super T>
编辑:它不适用于
Class<T>
和Class<? super T>
Class<? super T>
either. Class<? super T>
。
java.lang.Class
does not represent a type (use java.lang.reflect.Type
for that). java.lang.Class
不代表类型(为此使用java.lang.reflect.Type
)。 If T
, were say ArrayList<String>
then it makes no sense for there to be a Class<ArrayList<String>>
. 如果
T
为ArrayList<String>
则没有Class<ArrayList<String>>
。
It's worth noting that in this particular case there is no need for the method to be generic. 值得注意的是,在这种特殊情况下,不需要通用方法。
public static <T extends MyClass> void myMethod(T instance) {
Is equivalent to: 等效于:
public static void myMethod(MyClass instance) {
As per the Javadoc of the getClass
method : 按照
getClass
方法的Javadoc :
The actual result type is
Class<? extends |X|>
实际的结果类型是
Class<? extends |X|>
Class<? extends |X|>
where |X|Class<? extends |X|>
其中| X | is the erasure of the static type of the expression on whichgetClass
is called.是擦除在其上调用
getClass
的表达式的静态类型。 For example, no cast is required in this code fragment例如,此代码段中不需要强制转换
Here, the value for |X|
这里,
|X|
的值 in your code snippet is MyClass
, hence instance.getClass()
is assignable to only Class<? extends MyClass>
您的代码段中是
MyClass
,因此instance.getClass()
只能分配给Class<? extends MyClass>
Class<? extends MyClass>
or Class<?>
. Class<? extends MyClass>
或Class<?>
。
The reason for this specific wording is because when you say that for this variable having type T where <T extends MyClass>
, there can be multiple classes which extend MyClass
and hence capable of satisfying the T extends MyClass
criteria. 使用这种特定措辞的原因是因为当您说该类型为T的变量(其中
<T extends MyClass>
,可以存在多个扩展MyClass
类,因此能够满足T extends MyClass
条件。 Without runtime information there is no way of knowing which concrete implementation subclass of MyClass
was passed in the method. 没有运行时信息,就无法知道在方法中传递了
MyClass
哪个具体实现子类。 Hence to provide a generic solution, it returns <? extends MyClass>
因此,为了提供通用解决方案,它返回
<? extends MyClass>
<? extends MyClass>
since that would hold true for any subclass of MyClass
irrespective of what class instance is passed in. <? extends MyClass>
因为无论传入什么类实例,这对于MyClass
任何子类都适用。
Java does not support a generic type of <this> eg Java不支持<this>的通用类型,例如
Object could implement 对象可以实现
class Object {
Class<this> getClass()
}
But there is no way for getClass() to express that it will return a type which is the class of the object. 但是getClass()无法表示将返回一个类型,即对象的类。 The compiler has no native understand of what this method does either.
编译器也不了解此方法的功能。
IMHO, This behaviour should have been supported. 恕我直言,此行为应得到支持。
Instead of 代替
Class<? extends T> type = instance.getClass();
you need to use 你需要使用
Class<? extends MyClass> type = instance.getClass();
You cannot directly use the T
here. 您不能在此处直接使用
T
The reason is the method signature of Object.getClass()
(which you are invoking). 原因是
Object.getClass()
的方法签名(正在调用)。 It's: 它的:
public final Class<? extends Object> getClass()
So you are trying to convert from Class<? extends Object>
因此,您正在尝试从
Class<? extends Object>
转换Class<? extends Object>
Class<? extends Object>
to Class<? extends T>
Class<? extends Object>
到Class<? extends T>
Class<? extends T>
, which is not allowed (because you are down-casting). Class<? extends T>
,这是不允许的(因为您正在向下广播)。 It is allowed using an explicit cast: 它使用一个明确允许投:
Class<? extends T> type = (Class<? extends T>) instance.getClass();
will work (though it generates a type safety warning). 将起作用(尽管它会生成类型安全警告)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.