我希望从编译时间以及运行时方面来看,它不会成为问题 .getClass()
提供正确类型的返回值。
但我一定是错的。
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>
}
}
编辑: 它不起作用 Class<T>
和 Class<? super T>
无论是。
按照 Javadoc的 getClass
方法:
实际的结果类型是 Class<?
extends |X|>
其中| X |是擦除
表达式的静态类型
哪个 getClass
叫做。对于
例如,此处不需要强制转换
代码片段
在这里,值为 |X|
在你的代码片段中 MyClass
因此 instance.getClass()
只能分配给 Class<? extends MyClass>
要么 Class<?>
。
这个特定措辞的原因是因为当你说这个变量有类型T在哪里 <T extends MyClass>
,可以有多个类扩展 MyClass
因此能够满足 T extends MyClass
标准。没有运行时信息,就无法知道哪个具体的实现子类 MyClass
在方法中通过了。因此,为了提供通用解决方案,它返回 <? extends MyClass>
因为那对于任何子类都适用 MyClass
无论传递什么类实例。
java.lang.Class
不代表一种类型(使用 java.lang.reflect.Type
为了那个原因)。如果 T
,有人说 ArrayList<String>
那么就没有意义了 Class<ArrayList<String>>
。
值得注意的是,在这种特殊情况下,该方法不需要是通用的。
public static <T extends MyClass> void myMethod(T instance) {
相当于:
public static void myMethod(MyClass instance) {
代替
Class<? extends T> type = instance.getClass();
你需要使用
Class<? extends MyClass> type = instance.getClass();
你不能直接使用 T
这里。
原因是方法签名 Object.getClass()
(你要调用的)。它的:
public final Class<? extends Object> getClass()
所以你试图转换 Class<? extends Object>
至 Class<? extends T>
,这是不允许的(因为你是向下投射)。它 是 允许使用显式强制转换:
Class<? extends T> type = (Class<? extends T>) instance.getClass();
将起作用(虽然它会产生类型安全警告)。
Java不支持通用类型的<this>,例如
对象可以实现
class Object {
Class<this> getClass()
}
但getClass()无法表达它将返回一个类型,该类型是对象的类。编译器没有本机了解此方法的功能。
恕我直言,应该支持此行为。