java - 删除如何处理 Java 中的覆盖场景?

标签 java generics overriding

这个问题来 self 之前在 here. 中的帖子.在我发布问题之前,我粘贴了 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.

我对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参与是完全错误的。能不能给个简单的 举例说明上述观点。

谢谢。顺便说一句,以上几点来自here.

最佳答案

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

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

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.

  • Either:

    • m2 is public, protected, or declared with default access in the same package as C, or

    • m1 overrides a method m3 (m3 distinct from m1, m3 distinct from m2), such that m3 overrides m2.

要求 m1m2 的子签名,但反之则不行。

示例 1:

class A {
   public void foo(List<String> list) { }
}

class B extends A {
   @Override
   public void foo(List list) {}
}

这是合法的,因为Bfoo方法的签名和Afoo方法的删除是一样的。

示例 2:

class A {
   public void foo(List list) { }
}

class B extends A {
   @Override
   public void foo(List list) {}
}

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

示例 3:

class A {
   public void foo(List list) { }
}

class B extends A {
   @Override
   public void foo(List<Integer> list) {}
}

这是不合法的,因为没有考虑覆盖方法的删除。也就是说,将 List<Integer>List 的删除进行比较,后者仍然只是 List,它们并不相同。

示例 4:

class A {
   public void foo(List<String> list) { }
}

class B extends A {
   @Override
   public void foo(List<Integer> list) {}
}

这又是不合法的,因为没有考虑重写方法的删除。也就是说,将 List<Integer> 与删除 List<String> ( List ) 进行比较,它们不相同。

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

关于java - 删除如何处理 Java 中的覆盖场景?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21690268/

相关文章:

java - 获取给定 java Map 中的值的索引或键

Java协变/逆变与add/get

ios - 使用可用的 : <unknown>:0: error: 'xxx' is only available on iOS 11. 0 或更新版本覆盖 open var

java - 解析: Unauthorized in REST API

Java时间同步问题 多个时区客户端 单个数据库服务器

java - 图像在 bitmap.compress 后旋转

c# - 使用转换运算符转换对象失败

Scala 泛型 : How to declare that a type must be a case class?

c++ - 在C++中重写一个非void函数,supers的返回值返回到哪里?

oop - 通过 Scala 中的返回类型重写方法,oop 解决方案?