Подтвердить что ты не робот

Явное совпадение имени Java, имеет одно и то же стирание, и не скрывает другого

Я получаю ошибку столкновения этого имени, и я не знаю, как решить проблему. У меня есть два класса, и я использую перегруженный метод "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;
   }
}
4b9b3361

Ответ 1

Общее решение - использовать разные имена. Эти методы могут быть в классах без отношения наследования, поскольку они не являются методами экземпляра.

Как указано, реализация метода в вопросе одинакова (исключение опечатки).

(Эта проблема с перегрузкой часто путается с стиранием типов времени выполнения. Перегрузка - это время связи, а не динамическая проблема, поэтому ее можно легко фиксировать на языке. Это просто не очень полезное изменение, а не хорошее идея поощрять перегрузку.)

Ответ 2

Общий ответ:

Помимо проблемы одной и той же реализации здесь, суть проблемы заключается в том, что несколько варварский "метод A и метод B имеют одно и то же стирание".

Что делает этот вопрос сложным, так это то, что мы, как правило, не (по крайней мере, не этим утром) много знаем о типе Erasure.

Чтобы сделать это коротко:

Параметрические типы выполняют проверку типа во время компиляции (для обеспечения правильности ввода), но забудьте о своих параметрах типа во время выполнения (чтобы избежать генерации базовых методов).

Звучит в то же время просто и загадочно. Лучший способ понять это - обратиться к следующей литературе:

Надеюсь, что это поможет вам в той мере, в какой это помогло мне.

Конкретный ответ:

В вашем случае

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
   }
}

где один явно не может переопределить другой (не тот же самый параметр типа), но в то же время в точности совпадет во время выполнения (нет возможности для вашей программы выбрать, какой из них использовать).

Хватит этой проблемы, как ее решить? Вы можете выполнить один из следующих способов:

  • Используйте разные имена: createASensors и createBSensors этот подход является наиболее очевидным, но выглядит немного менее изящным.

  • Добавьте параметр: createSensors(Collection<? extends ClassA> list, ClassA typeDefiner) этот подход может показаться варварским, но немного менее изящным, но используется в java.util.List для метода <T> T[] toArray(T[] a).

Ответ 3

Проверьте настройки проекта и версию компилятора проекта. Щелкните правой кнопкой мыши по проекту → Свойства → Компилятор Java. Убедитесь, что настройка соответствия обновлена. У меня была эта проблема, когда параметры соответствия были установлены на 1.4 вместо 1.6