【问题标题】:Override java generic method in interface覆盖接口中的java泛型方法
【发布时间】:2014-05-23 01:03:01
【问题描述】:
public   <A extends Interface1,I extends Interface2> I  Method(A a);

这是一个接口中的方法。当我要重写此接口方法时,我可以用任何实现 Interface2 的类替换 I,但如果参数 A 是 Interface1 的子类,则它会被拒绝。它只能是 Interface1 类型。所以当我尝试时:

 public   SubTypeofInterface2  Method(Interface1 a); //fine
 public   SubTypeofInterface2  Method(SubTypeofInterface1 a); // not accepted

为什么会这样?

【问题讨论】:

  • 在这个例子中你的泛型是多余的。

标签: java generics interface


【解决方案1】:

只有当两个方法的擦除相同或实现类中的方法擦除与接口中方法的擦除兼容时,才认为实现类中的方法重写了接口方法。

那么接口中方法的擦除是什么?是这样的:

public Interface2 method(Interface1 a);

所以,在你的两种方法中:

public   SubTypeofInterface2  Method(Interface1 a); //fine
public   SubTypeofInterface2  Method(SubTypeofInterface1 a); // not accepted

只有第一个覆盖与擦除方法兼容。允许返回类型中的协变类型。

但是第二种方法不兼容覆盖。重写时参数中不允许使用协变类型。这就是它无法编译的原因。

它的工作方式与普通的非泛型方法覆盖相同:

interface Test {
    Object get(Object obj);
}

class TestImpl implements Test {
    // Valid override
    @Override
    public String get(Object obj) { return null; }

    // This doesn't override interface method.
    public String get(String obj) { return null; }
}

【讨论】:

    【解决方案2】:

    这是因为您的方法需要能够处理 Interface1 的任何子类型。如果用户想要将 Interface1 的 不同 子类型传递到您的方法中会发生什么?该接口告诉用户他们可以,但您对该接口的实现不同意。因此出现错误。

    【讨论】:

      【解决方案3】:

      查找“逆变”。方法参数处于逆变位置。即使 Java 足够酷以支持这种子类型关系,您的子类也必须看起来像

      public   SubTypeofInterface2 Method(SuperTypeofInterface1 a);
      

      【讨论】:

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