擦除如何处理Java中的覆盖场景?

bra*_*orm 6 java generics overriding

这个问题来自我之前的帖子..在发布我的问题之前,我正在粘贴oracle文档中的内容;

8.4.8.1. Overriding (by Instance Methods)

An instance method m1, declared in class C, overrides another instance method m2, declared in class A iff all of the following are true:

    C is a subclass of A.

    The signature of m1 is a subsignature (§8.4.2) of the signature of m2.

8.4.2. Method Signature 
The signature of a method m1 is a subsignature of the signature of a method m2 if either:

    m2 has the same signature as m1, or

    the signature of m1 is the same as the erasure (§4.6) of the signature of m2.
Run Code Online (Sandbox Code Playgroud)

我对type erasure何时overriding涉及的理解如下:如果之后erasure,signature of m1 and m2相同,则考虑它们overridden.所以在我以前的上面的帖子,我想override一个parent class method是需要 List<String>通过subclass method这需要List<Integer>经过假设type erasure 剩下就是List<Object>.但那是错的.所以我的方法的上述定义的理解overriding时,erasure涉及的是完全错误的.可以举出一些简单的例子来解释上述观点.

谢谢.顺便说一句,以上几点来自这里.

rge*_*man 3

一个方法是否覆盖另一个方法不仅仅涉及方法的删除。编译器确定一个方法是否覆盖另一个方法,并且它可以在类型擦除发生之前访问所涉及的泛型类型参数。

\n

您关于使用擦除来确定覆盖的想法不太正确。让我们将以下JLS 部分 8.4.8.1添加到讨论中:

\n
\n

在类 C 中声明的实例方法 m1 重写在类 A 中声明的另一个实例方法 m2,当且仅当满足以下所有条件时:

\n
    \n
  • C是A的子类。

    \n
  • \n
  • m1 的签名是 m2 签名的子签名 (\xc2\xa78.4.2)。

    \n
  • \n
  • 任何一个:

    \n
      \n
    • m2 是公共的、受保护的或在与 C 相同的包中以默认访问权限声明的,或者

      \n
    • \n
    • m1 覆盖方法 m3(m3 与 m1 不同,m3 与 m2 不同),使得 m3 覆盖 m2。

      \n
    • \n
    \n
  • \n
\n
\n

要求 是m1的子签名m2,但反之则不然。

\n

示例1:

\n
class A {\n   public void foo(List<String> list) { }\n}\n\nclass B extends A {\n   @Override\n   public void foo(List list) {}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

B这是合法的,因为\的方法的签名与\的方法foo的擦除是相同的。Afoo

\n

示例2:

\n
class A {\n   public void foo(List list) { }\n}\n\nclass B extends A {\n   @Override\n   public void foo(List list) {}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是合法的,因为签名是相同的(即使它们是原始的)。

\n

示例3:

\n
class A {\n   public void foo(List list) { }\n}\n\nclass B extends A {\n   @Override\n   public void foo(List<Integer> list) {}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是不合法的,因为没有考虑覆盖方法的擦除。也就是说List<Integer>与 的擦除相比List,仍然只是List,而且它们并不相同。

\n

示例4:

\n
class A {\n   public void foo(List<String> list) { }\n}\n\nclass B extends A {\n   @Override\n   public void foo(List<Integer> list) {}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这又是不合法的,因为没有考虑覆盖方法的擦除。即与( )List<Integer>的擦除相比,它们并不相同。List<String>List

\n

您不能更改重写方法中参数的泛型类型参数(例如List<String>to List<Integer>)。当重写不使用泛型的方法时(例如 ( Listto List<Integer>)),您不能引入泛型。但是,您可以在重写时删除泛型(例如List<String>to List)。

\n