我希望从编译时间以及运行时方面来看,.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>
。
答案 0 :(得分:6)
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) {
答案 1 :(得分:3)
根据the Javadoc of the getClass
method:
实际结果类型为
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
的任何子类。
答案 2 :(得分:0)
Java不支持泛型类型&lt; this&gt; e.g。
对象可以实现
class Object {
Class<this> getClass()
}
但getClass()无法表达它将返回一个类型,该类型是该对象的类。编译器对本方法的作用没有本地的理解。
恕我直言,应该支持此行为。
答案 3 :(得分:0)
而不是
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();
将起作用(尽管它会生成类型安全警告)。