Java名称冲突,具有相同的擦除,既不隐藏另一个

时间:2012-12-22 12:47:45

标签: java generics name-clash

我收到此名称冲突错误,我不知道该如何解决问题。 我有两个类,我使用重载方法“createSensors”。这里简化的是产生问题的代码:

public abstract class ClassA {
    public static List<Sensor> createSensors(Collection<? extends ClassA> list) {
        List<Sensor> sensors = new ArrayList<Sensor>();
        for (ClassA s : list) {
           sensors.add(s.getSensor());
        }
        return sensors;
    }
}

public abstract class ClassB extends ClassA {
    public static List<Sensor> createSensors(Collection<? extends ClassB> list) {
        List<Sensor> sensors = new ArrayList<Sensor>();
        for (ClassB s : list) {
           sensors.add(s.getSensor());
        }
        return sensors;
   }
}

3 个答案:

答案 0 :(得分:13)

一般答案:

除了这里实现相同的问题之外,问题的核心是,有点野蛮,“方法A和方法B具有相同的擦除”。

使一个复杂的问题是,我们通常不会(至少我今天早上没有)对“类型擦除”了解很多。

简而言之:

  

参数类型在编译时执行类型检查(以确保类型正确性)但在运行时忘记它们的类型参数(以避免生成基础方法)。

这听起来简单而令人费解。 理解它的最佳方式是参考以下文献:

  1. What is a reifiable type ?
  2. How and under what conditions is erasure performed ?
  3. Have you any idea/examples about what it could imply in my coding life ?
  4. Well that's odd and I don't really like it but I'm curious why they did that ...
  5. 希望能帮助你,帮助我。

    具体答案:

    在你的情况下

    public abstract class ClassA {
        public static List<Sensor> createSensors(Collection<? extends ClassA> list) {
            //do stuff
        }
    }
    
    public abstract class ClassB extends ClassA {
        public static List<Sensor> createSensors(Collection<? extends ClassB> list) {
            //do other stuff
       }
    }
    

    将由javac“转换”为

    public abstract class ClassA {
        public static List createSensors(Collection list) {
            //do stuff
        }
    }
    
    public abstract class ClassB extends ClassA {
        public static List createSensors(Collection list) {
            //do other stuff
       }
    }
    

    其中一个显然不能覆盖另一个(不是相同的类型参数)但最终在运行时完全相同(程序无法选择使用哪个)。

    这个问题够了,怎么解决呢? 您可以继续使用以下方法之一:

    • 使用不同的名称:createASensorscreateBSensors 这种方法最明显,但看起来不那么优雅。

    • 添加参数:createSensors(Collection<? extends ClassA> list, ClassA typeDefiner) 这种方法看起来很野蛮,但有点不那么优雅,但是java.util.List用于方法<T> T[] toArray(T[] a)

答案 1 :(得分:5)

一般的解决方案是使用不同的名称。这些方法可以在没有继承关系的类中,因为它们不是实例方法。

正如所指出的,问题中的方法实现是相同的(错误除外)。

(这个重载问题常常与删除运行时类型混淆。重载是一个链接时间而不是动态问题,所以可以很容易地用语言修复。这不是一个特别有用的改变,而不是一个好的鼓励超载的想法。)

答案 2 :(得分:-2)

检查项目的项目设置和编译器版本。右键单击项目 - &gt;属性 - &gt; Java编译器。确保合规性设置是最新的。当合规性设置设置为1.4而不是1.6

时,我遇到了这个问题