首页 > 解决方案 > 在java中使用类型擦除覆盖/重载方法

问题描述

使用给定的 2 个类:

public class A{
    public <T> Cell<T> f(Cell<T> l){
        return null;
    }
}
public class B extends A{
    public <T> Cell<T> f(Cell<Cell<T>> l){ // trying to override
        return null;
    }
}

(当 Cell 是一些通用类时)。

我知道在类型擦除之后,类看起来像:

public class A{
    public Cell f(Cell l){
        return null;
    }
}
public class B extends A{
    public Cell f(Cell l){ // trying to override
        return null;
    }
}

在我知道类型擦除之前,我认为我确实理解了为什么编译器将其视为重载。

但是现在我(认为)我知道类型擦除,这两个方法签名是相同的,我真的认为编译器将其视为覆盖更有意义。

编译它之后,得到 java 的编译器认为这是试图 OVERLOAD 而不是覆盖,并产生一个重载到相同签名方法的错误。

我的问题:为什么编译器仍然认为这是对 OVERLOADING 而不是 OVERRIDING 的尝试,尽管在类型擦除之后签名是一样的?

谢谢!

标签: javagenericsoverridingoverloadingtype-erasure

解决方案


“使用相同签名重载”的错误在这里似乎足够了。它在技术上不是压倒一切的,因为对于编译器泛型很重要,并且 B 的 f 不满足 A 的签名,因为 A 的 f T 不限于实现Cell<?>,因此 B 的 f 不会覆盖 A 的 f;将其称为“重载”更有意义,因为在通用方面这些签名是不同的,尽管在擦除后最终是相同的。

我认为在这种特殊情况下添加了“具有相同签名的重载”错误,泛型会导致擦除冲突。


推荐阅读