【问题标题】:Why overriding a generic method requires same bounds?为什么覆盖泛型方法需要相同的界限?
【发布时间】:2019-12-05 00:59:35
【问题描述】:

对于普通(非泛型)方法,要求子方法与父方法的擦除等效。

但是对于泛型方法,子方法需要有相同类型的参数,这意味着每个参数有相同的界限,例如:

public abstract class Parent {
    public abstract <T> T example( Map<String, Integer> map) throws Exception;
}
public class Son1 extends Parent {
// this could work
    @Override
    public <T> T example(Map<String, Integer> map) throws Exception {
        return null;
    }
}

public class Son2 extends Parent {
// and this couldn't work
    @Override
    public <T> T example(Map map) throws Exception {
        return null;
    }
}
public class Son3 extends Parent {
// and this could work
    @Override
    public Object example(Map map) throws Exception {
        return null;
    }
}

我可以找到这项检查的完成地点(hasSameBounds)。

为什么 Son2 不工作? JLS中有描述吗?

【问题讨论】:

  • 不,用参数类型为Map 的方法覆盖参数类型为Map&lt;String, Integer&gt; 的方法始终是一个问题——它总是导致“原始类型”。原始类型只是为了向后兼容 Java 1.5 之前的代码。在 public &lt;T&gt; T example(Map map) 中的方法中将原始类型与泛型类型参数结合起来根本没有意义(因为原始类型仅存在于不理解泛型的代码中)并且被拒绝。
  • @ErwinBolwidt Son3的情况是为了向后兼容,在JLS中有描述。但我找不到为什么 Son2 不能工作,而 Son1 可以在 JLS 中工作。这就是问题所在。

标签: java jls


【解决方案1】:
ParentT example( Map&lt;String, Integer&gt; map)

The erasure of the signatureT example(Map map)

Son2T example(Map map) 的签名与擦除相同ParentT example( Map&lt;String, Integer&gt; map) 的签名。这使得两个签名的“override-equivalent”。

...为什么 Son2 不起作用?...

Son2 不起作用,因为它与 Parent覆盖等效

...JLS 中有描述吗?...

是的。有……

§8.4.2 Method Signature

在一个类中声明两个具有重写等效签名的方法是编译时错误。

示例 8.4.2-1。覆盖等效签名

class Point {
    int x, y;
    abstract void move(int dx, int dy);
    void move(int dx, int dy) { x += dx; y += dy; }
}

此程序会导致编译时错误,因为它声明了两个具有相同(因此,覆盖等效)签名的 move 方法。即使其中一个声明是abstract,这也是一个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多