当前位置: 首页 > 面试题库 >

Java泛型:为什么someObject.getClass()不返回Class ?

邹曦之
2023-03-14
问题内容

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


问题答案:

根据该getClass方法的Javadoc:

实际结果类型为Class<? extends |X|>| X |
是擦除其getClass上调用的表达式的静态类型。例如,此代码段中不需要强制转换

在此,|X|您的代码段中的值为MyClass,因此instance.getClass()只能分配给Class<? extends MyClass>Class<?>

使用这种特定措辞的原因是因为当您说该变量具有类型T其中where时<T extends MyClass>,可以存在多个扩展的类,MyClass因此能够满足T extends MyClass条件。没有运行时信息,就无法知道MyClass方法中传递了哪个具体的实现子类。因此,为了提供一个通用的解决方案,它会返回,<? extends MyClass>因为MyClass无论传入什么类实例,这对于任何子类都适用。



 类似资料:
  • 问题内容: 我正在使用泛型编写某些东西,令我惊讶的是,我发现这行不通: 那我不能实例化泛型吗?没有任何方法可以做到这一点吗? 问题答案: 是的,这真是令人讨厌。 我使用的解决方法是强制客户端在构造新类时传递类-即 然后您可以使用。

  • 问题内容: 我正在尝试使用泛型实现以下结构。收到编译器错误,无法找出原因。 这个想法是译者使用T作为字典中键的类型。例如,可以是字符串或枚举。子类提供具体的字典。 但是它失败,因为:“类型’String’不符合协议’Hashable’” 但是String符合Hashable。它也不适用于Int,后者也符合Hashable。 如果删除类型约束,则仅用于测试(在此我还必须禁用字典,因为我不能在其中使用

  • 问题内容: 为什么Java中的泛型只能用于类,而不能用于原始类型? 例如,这可以正常工作: 但这是不允许的: 问题答案: ava中的泛型是一个完全编译时的结构-编译器将所有泛型使用转换为正确的类型。这是为了保持与以前的JVM运行时的向后兼容性。 这个: 变成(大致): 因此,任何用作泛型的东西都必须可转换为Object(在此示例中返回),而原始类型则不是。因此它们不能用于泛型。

  • 为什么Java中的泛型可以处理类而不能处理基元类型? 例如,这个操作很好: 但这是不允许的:

  • 问题内容: 考虑以下代码: 如果我用以下命令编译它: 它返回: 请注意,即使在返回类型上未引用任何泛型类型,也仅将泛型方法视为不安全。 这是一个错误吗?还是有一个更深层次的原因我没有考虑? 问题答案: 允许使用原始类型以确保与引入泛型之前编写的代码兼容。原始类型的工作原理是,仅从所有方法参数和返回类型中忽略 所有 类型信息,甚至与该类的类型参数无关的类型信息。正如您所发现的,这可能导致奇怪的结果。

  • 我在我的Java程序中写了这个函数: 这就是我所说的: 它是有效的,但我觉得我应该能够省略第一个参数,并从返回类型(结果被分配到的类型)推断出它。这可能吗?如果是,语法是什么?