Java泛型-方法重写

Java泛型-方法重写,java,generics,Java,Generics,我有一对类别a和类别B,如下所示。 案例1: 我这里有两个问题。 [q1] 如果我这么说,case2是case1的运行时表示(在类型擦除之后),对吗 [q2] 如果我对[q1]的看法是正确的,那么为什么案例1被接受为有效的覆盖?(我知道为什么case2不是有效的覆盖,因为参数不同。) 请有人解释一下。 提前感谢。对[q1]的回答是否定的。 编译器将在ClassB中生成一个桥接方法,该桥接方法将实际覆盖方法(Number) 您将在on-type擦除中得到完整答案。实际的ClassB超类是Class

我有一对类别a和类别B,如下所示。
案例1:

我这里有两个问题。
[q1] 如果我这么说,case2是case1的运行时表示(在类型擦除之后),对吗

[q2] 如果我对[q1]的看法是正确的,那么为什么案例1被接受为有效的覆盖?(我知道为什么case2不是有效的覆盖,因为参数不同。)

请有人解释一下。 提前感谢。

对[q1]的回答是否定的。 编译器将在
ClassB
中生成一个桥接方法,该桥接方法将实际覆盖
方法(Number)


您将在on-type擦除中得到完整答案。

实际的
ClassB
超类是
ClassA
。因此,其成员函数
方法
具有编译时签名:

void method(Integer t){}
您可以通过调用以下命令来说服自己

ClassA a = new ClassB();
a.method(1.0);
您应该会看到一个运行时错误。事实上,只可能编译它,因为我使用了
ClassA
的擦除版本。事实上,每一项任务都是为了 除
ClassA
(例如
ClassA)以外的泛型类型将由于不兼容的类型而失败

在Java中(自版本5以来),重写方法的返回类型必须是协变的,并且重写方法的参数必须是逆变的

这意味着重写类可以在返回的内容上更加具体,在接收的内容上更加接受

在第二个示例中,想象一个
ClassA
类型的变量,其值为
ClassB

 ClassA a = new ClassB(); // This is legal, since ClassB is a subclass of ClassA
 a.method(1.0); // This is legal, since ClassA.method accepts Number
但是,另一种方式也可以:

public class ClassC { public Number method(Integer i) {...} }
public class ClassD extends ClassC {
   @Override 
   public Integer method(Number n) {...}
}

有效,因为
ClassD
仍然履行
ClassC
案例1
中定义的合同,所以指定
T
Integer
,因此用
T=Integer
覆盖是有效的。但是
Number
不是
Integer
,如果它是
-1,那就行了,对不起。这是错误的:重写方法的参数类型必须完全匹配。相反是不够的。您的示例代码将无法编译。
ClassA a=new ClassB();a、 方法(1.0)仅因原始类型而有效。(它将抛出一个
ClassCastException
)此外,Java中的方法重写不允许使用逆变参数。您是对的。必须为逆变参数创建桥接方法。
ClassA a = new ClassB();
a.method(1.0);
 ClassA a = new ClassB(); // This is legal, since ClassB is a subclass of ClassA
 a.method(1.0); // This is legal, since ClassA.method accepts Number
public class ClassC { public Number method(Integer i) {...} }
public class ClassD extends ClassC {
   @Override 
   public Integer method(Number n) {...}
}