试图理解"两种方法都有相同的擦除,但都没有超越另一种"的情况

use*_*ult 9 java

我正在尝试解决问题,我想出了这个解决方案(简化):

package help;

public class Problem {

    private static class A<T> {
        public void foo(T t) {}
    }

    private static class B<T> {}

    private static class C<T> extends A<B<T>> {
        public void foo(T t) {}
    }
}
Run Code Online (Sandbox Code Playgroud)

它不会编译,因为help.Problem.C中的"foo(T)与help.Problem.A中的foo(T)冲突;两种方法都有相同的擦除,但都没有覆盖其他方法".

我不只是想解决问题,我也想了解发生了什么.我注意到如果省略B类,则错误消失了.

另外:你能提供一段代码的例子,编译器无法将变量绑定到这两个方法中的一个吗?

Mic*_*rry 5

的类定义A意味着编译器“期望”这样的东西,如果你想覆盖foo

private static class C<T> extends A<B<T>> {
    public void foo(B<T> t) {}
}
Run Code Online (Sandbox Code Playgroud)

但是,因为你只是提供T一个类型到方法,而不是B<T>,这不是一个有效的覆盖fooA-参数类型必须匹配。这不会导致非泛型类型的错误 - 您刚刚获得了一个重载方法(一种具有相同名称但其参数的类型/数量不同的方法)而不是被覆盖的方法。

但是,由于泛型类型在编译时消失(通过类型擦除),这意味着您不能有两种仅通过泛型类型区分的方法,因为它们在字节码中的定义是相同的。

  • @userfault 没问题,乐于助人。 (3认同)