简体   繁体   English

两种方法都有相同的擦除,但都没有覆盖另一个

[英]Both methods have same erasure yet neither overrides the other

I have this code:我有这个代码:

class A {
    public void func(String str, List<String> lst) {}

}

class B extends A {
    public void func(String str, List<Integer> lst) {}  // Does not compile
}

The line with the comment does not compile with the following explanation: "both methods have same erasure yet neither overrides the other".带有注释的行没有与以下解释一起编译:“两种方法都具有相同的擦除,但都没有覆盖另一个”。 On the one hand, I understand that it is not overriding, since the generic type in the second argument is different.一方面,我知道它不是重写的,因为第二个参数中的泛型类型不同。 On the other hand, after erasure both functions have essentially the same signature, so it is not overloading either.另一方面,在擦除之后,两个函数的签名基本相同,所以它也没有重载。 But I am struggling to understand why it doesn't compile.但我很难理解为什么它不能编译。 Any help would be appreciated.任何帮助,将不胜感激。

ADDED: Even if I change the signature to添加:即使我将签名更改为

public Object func(String str, List<Integer> lst) {return null;}

It still does not compile, with the same reason.它仍然无法编译,原因相同。 Now these are different signatures altogether, so it makes me even more confused.现在这些完全是不同的签名,所以这让我更加困惑。

From JLS 8.4.2 :JLS 8.4.2开始:

Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the type parameters of M, the same formal parameter types .如果两个方法或构造函数 M 和 N 具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在将 N 的形式参数类型调整为M,相同的形参类型

How is that relevant to your code?这与您的代码有什么关系?

  1. The first method signature you posted is:您发布的第一个方法签名是:

     public void func(String str, List<String> lst)

    This signature exists like this only at compile-time because it uses generics.此签名仅在编译时存在,因为它使用泛型。 Once compiled, the runtime signature will be like below ( List<String> becomes List ) due to type erasure:编译后,由于类型擦除,运行时签名将如下所示( List<String>变为List ):

     public void func(String str, List lst)
  2. The second method signature in your example is:您示例中的第二个方法签名是:

     public void func(String str, List<Integer> lst)

    While the starting point is different – a List of Integer instead of a List of String – the runtime signature for this sees a similar change, replacing List<Integer> with List :虽然起点不同——一个整数列表而不是字符串列表——运行时签名看到了类似的变化,将List<Integer>替换为List

     public void func(String str, List lst)

Even though your code specifies differences in the argument list ( List<String> vs List<Integer> ) which leads you to believe there are two different method signature, the two signatures are effectively the same:即使您的代码在参数列表( List<String>List<Integer> )中指定了差异,这使您相信存在两个不同的方法签名,但这两个签名实际上是相同的:

  • they are both named "func", and它们都被命名为“func”,并且
  • they have the same argument list: String, List他们有相同的参数列表:字符串,列表

In Erasure of Generic Types , they show an example similar to what you're seeing where a type of Node<T> becomes Node .Erasure of Generic Types中,他们展示了一个类似于您所看到的Node<T>类型变为Node的示例。 That is happening with your examples, too, where List<String> becomes List .这也发生在您的示例中,其中List<String>变为List

During the type erasure process, the Java compiler erases all type parameters and replaces each with its first bound if the type parameter is bounded, or Object if the type parameter is unbounded.在类型擦除过程中,Java 编译器擦除所有类型参数,如果类型参数是有界的,则将每个类型参数替换为其第一个边界,如果类型参数是无界的,则将其替换为 Object。

Note that the return type is not part of a method signature uniqueness, which is why changing one to return Object didn't make a difference.请注意,返回类型不是方法签名唯一性的一部分,这就是为什么将其更改为返回Object并没有什么不同。

Here's a bit more info from the Java Tutorial section on Type Erasure , with a little emphasis added in a few spots:以下是关于Type Erasure的 Java 教程部分的更多信息,并在一些地方添加了一些重点:

Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming.泛型被引入 Java 语言以在编译时提供更严格的类型检查并支持泛型编程。 To implement generics, the Java compiler applies type erasure to:为了实现泛型,Java 编译器将类型擦除应用于:

  • Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded.如果类型参数是无界的,则将泛型类型中的所有类型参数替换为其边界或 Object。 The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods .因此,生成的字节码只包含普通的类、接口和方法
  • Insert type casts if necessary to preserve type safety.必要时插入类型转换以保持类型安全。
  • Generate bridge methods to preserve polymorphism in extended generic types.生成桥方法以保留扩展泛型类型中的多态性。 Type erasure ensures that no new classes are created for parameterized types;类型擦除确保不会为参数化类型创建新类; consequently, generics incur no runtime overhead.因此,泛型不会产生运行时开销。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 两种方法具有相同的擦除,但是都不能覆盖另一种方法 - Both methods have same erasure, yet neither overrides the other “'Mapper' 中的 map(From)' 与 'CursorToMessageImpl' 中的 'map(Object)' 冲突;两种方法具有相同的擦除,但都不会覆盖另一个 - "map(From)' in 'Mapper' clashes with 'map(Object)' in 'CursorToMessageImpl'; both methods have same erasure, yet neither overrides the other 在实现ConsumerSeekAware接口时,如何使“这两种方法都具有相同的擦除能力,但两者都不能覆盖另一个方法”的警告静音? - How do I silence the “both methods have same erasure yet neither overrides the other” warning while implementing the ConsumerSeekAware interface? 无法覆盖onBeforeConvert:“......有相同的删除,但都没有覆盖其他” - Cannot Override onBeforeConvert: “…have the same erasure, yet neither overrides the other” 集具有相同的擦除,但没有一个覆盖另一个错误 - Set have the same erasure, yet neither overrides the other error SkuDetailsResponseListener() 中的“两种方法都具有相同的擦除功能,但都不会覆盖另一个”方法冲突错误 - 'Both methods have same erasure, yet neither overides the other' method clash error in SkuDetailsResponseListener() 实现Comparable,compareTo名称冲突:“具有相同的擦除,但不会覆盖其他” - Implementing Comparable, compareTo name clash: “have the same erasure, yet neither overrides the other” 名称冲突 - 具有相同的擦除但在方法参数generic中不会覆盖另一个 - Name clash - have the same erasure yet neither overrides the other in method parameter generic 具有相同的擦除,但不能覆盖仅在一种情况下出现的其他警告 - Have same erasure, yet neither overrides the other warning appearing in only ONE situation 界面和一个类。名称冲突:相同的擦除,但都不会覆盖其他 - interface and a class. name clash: same erasure, yet neither overrides other
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM