【问题标题】:How does method over riding work in case where method signature remains same but generic parameters differ?在方法签名保持不变但泛型参数不同的情况下,方法覆盖如何工作?
【发布时间】:2012-02-29 23:22:01
【问题描述】:

我正在尝试以下示例:

class BaseClass {
    public void methodA(Class<?> cl) {
        System.out.println("Base.methodA()");
    }
}

class SubClass extends BaseClass {
    public void methodA(Class cl) {
        System.out.println("Sub.methodA()");
    }
}

public class OverrideEx {

    public static void main(String[] args) {
        BaseClass b = new BaseClass();
        BaseClass s = new SubClass();

        b.methodA(Class.class);
        s.methodA(Class.class);
    }
}

输出: Base.methodA() Sub.methodA()

但是如果我改变骑行方法参数如下:

class BaseClass {
    public void methodA(Class cl) {
        System.out.println("Base.methodA()");
    }
}

class SubClass extends BaseClass {
    public void methodA(Class<?> cl) {
        System.out.println("Sub.methodA()");
    }
}

public class OverrideEx {

    public static void main(String[] args) {
        BaseClass b = new BaseClass();
        BaseClass s = new SubClass();

        b.methodA(Class.class);
        s.methodA(Class.class);
    }
}

我得到编译错误。它说“名称冲突:SubClass 类型的方法 methodA(Class) 与 BaseClass 类型的 methodA(Class) 具有相同的擦除,但不会覆盖它”。

为什么会这样?

【问题讨论】:

标签: java generics overriding


【解决方案1】:

参数化类型 Class&lt;?&gt; 是原始类型 Class4.10.2) 的子类型。

因此,对于任何x,如果重写,第一个示例中的调用s.methodA(x) 也将有效:

((BaseClass)s).methodA(x)

第二个例子不是这样。

假设x 属于Class 类型,它不是Class&lt;?&gt; 的子类型。那个电话 将是非法的,因为参数的类型不是形参类型的子类型。

这意味着methodASubClass 不会覆盖methodABaseClass

【讨论】:

    【解决方案2】:

    根据JLS,您可以覆盖一个方法,如果(除其他外):m1 的签名是 m2 签名的子签名(第 8.4.2 节)。 p>

    这意味着(JLS again):
    - m2 与 m1 具有相同的签名,或者
    - m1的签名和m2的签名擦除一样。

    在您尝试覆盖methodA 时,您有相同的类型擦除,但您没有相同的签名。在 jls 的这一章中,对您所描述的问题进行了讨论。

    【讨论】:

      猜你喜欢
      • 2014-08-21
      • 1970-01-01
      • 2015-05-22
      • 1970-01-01
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-03
      相关资源
      最近更新 更多