Java泛型:为什么someObject.getClass()不';t返回类<;?扩展T>;?

Java泛型:为什么someObject.getClass()不';t返回类<;?扩展T>;?,java,class,generics,types,type-safety,Java,Class,Generics,Types,Type Safety,我希望从编译时和运行时的角度来看,.getClass()提供正确类型的返回值不会有问题 但我一定错了 public class _GetClassGenerics2 { static class MyClass { } public static void main(String[] args) { MyClass myInstance = new MyClass(); // here it works Class<? extends MyClass

我希望从编译时和运行时的角度来看,
.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>
  }

}
public类\u GetClassGenerics2{
静态类MyClass{
}
公共静态void main(字符串[]args){
MyClass myInstance=新的MyClass();
//它在这里工作

类Java不支持泛型类型,例如

对象可以实现

class Object {
    Class<this> getClass()
}
类对象{
类getClass()
}

但是getClass()无法表示它将返回一个作为对象类的类型。编译器也不了解这个方法的本族语

依我看,应该支持这种行为。

而不是

Class<? extends T> type = instance.getClass();

因此,您试图从
Class
转换java.lang.Class
并不表示类型(使用
java.lang.reflect.type
),如果
T
,比如说
ArrayList
,那么存在
类就没有意义了

值得注意的是,在这种特殊情况下,方法不需要是泛型的

public static <T extends MyClass> void myMethod(T instance) {
根据:

实际结果类型为
Class


之所以使用这种特定的措辞,是因为当您说对于类型为T的变量,其中
,可以有多个类扩展
MyClass
,因此能够满足
T扩展MyClass
标准。如果没有运行时信息,就无法知道哪些具体实现是
MyClass
的ubclass已在方法中传递。因此,为了提供通用解决方案,它返回
How-about
ClassFound一个可能解释它的问题:
@sjngm
:1)请参见编辑,2)给定的其他问题没有那么相关,I(通常)理解
super
extends
之间的区别。这不是问题,但问题是为什么。有原因吗?在这一点上,我们知道实例必须是t类中的任何一个(不管是什么)或者它的子类。那么为什么不允许扩展T
?谢尔盖:原因是,虽然我们知道
实例
必须是
T
类型或子类,但
对象。getClass()
没有考虑到这一点。请看我编辑的答案。我仍然不明白。javadoc说“实际结果类型为Class@Sergey:编译器不关心
getClass()
的“实际结果类型”。编译器进行静态类型检查,因此只关心方法签名。签名表示
ClassBy“实际结果类型”Javadoc表示“签名的实际结果类型”或“静态返回类型”因为它还提到不需要显式强制转换(对于实际的结果类型),所以它不是真正的答案。真正的答案在Sanjay的答案的注释中提到。答案很好。但是请注意,您在第一步之前解释了第二步。直接的问题是Object.getClass()没有返回“right”类型。你解释它为什么不这样做。你能指出任何解释什么是
的资源吗?我在语言规范中找不到它,也不能编译类似的东西。对不起,Java确实支持“this type”功能?这很好,但我想你的意思是不支持,对吗?因为
类getSomething()
不起作用。@java.is.for.desktop感谢您选择它,现在就修复它。“但是getClass()无法表示它将返回一个对象类的类型。”根据该逻辑,
getClass()
“也无法表示”它返回
classi,但我没有得到,这就是为什么X是MyClass,而不是t。@Sergey Tachenov:因为AFAICT,
|X |
是一个擦除,因此不能是参数化类型。如果它只是
t
,Javadoc就不会明确提到静态类型的擦除。哦,我终于得到了。语言规范4.6明确指出t“类型变量(§4.4)的删除是其最左边边界的删除”。在我们的例子中,这就是MyClass。我不明白他们为什么这样做。@Sergey:那是因为当你说这个变量的类型为
t
,其中
,可以有多个类扩展
MyClass
,因此能够满足
t扩展MyClass
标准。没有运行时通知没有办法知道方法中传递了
MyClass
的哪个具体实现子类。因此,为了提供一个通用解决方案,它返回
,因此基本上是因为没有办法确保在编译时强制转换是正确的,因为T的实际类型未知?我想我现在知道了。顺便说一下,请如果要修改您的答案,编辑中缺少一些代码。
public final Class<? extends Object> getClass()
Class<? extends T> type = (Class<? extends T>) instance.getClass();
public static <T extends MyClass> void myMethod(T instance) {
public static void myMethod(MyClass instance) {