Ява имя столкновения, имеют то же самое стирание, ни один не скрывает другой
Я получаю сообщение об ошибке "конфликт имен", и я не знаю, как мне решить эту проблему. У меня есть два класса, и я использую перегруженный метод "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 ответа
Общее решение - использовать разные имена. Эти методы могут быть в классах без отношения наследования, поскольку они не являются методами экземпляра.
Как указано, реализация метода в вопросе одинакова (опечатка исключена).
(Эта проблема с перегрузкой часто путается со стиранием типов времени выполнения. Перегрузка - это проблема времени соединения, а не динамическая проблема, поэтому ее можно легко исправить в языке. Это просто не особенно полезное изменение и не очень хорошая идея поощрять перегрузка.)
Общий ответ:
Помимо проблемы той же реализации здесь, ядро проблемы состоит в том, что, несколько варварский, "метод A и метод B имеют одинаковое стирание".
Что усложняет вопрос, так это то, что мы, как правило, не знаем (по крайней мере, сегодня утром) о "стирании типов".
Чтобы сделать это коротким:
Параметрические типы выполняют проверку типа во время компиляции (для обеспечения правильности типа), но забывают свои параметры типа во время выполнения (чтобы избежать генерации базовых методов).
Это звучит одновременно просто и загадочно. Лучший способ понять это - обратиться к следующей литературе:
- Что такое тип reifiable?
- Как и при каких условиях выполняется удаление?
- Есть ли у вас идеи / примеры того, что это может означать в моей жизни кодирования?
- Ну, это странно, и мне это не очень нравится, но мне любопытно, почему они это сделали...
Надеюсь, это поможет вам так же, как и мне.
Конкретный ответ:
В твоем случае
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
}
}
будет "преобразован" Джаваком в
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)
,
Проверьте настройки проекта и версию компилятора проекта. Щелкните правой кнопкой мыши по проекту -> Свойства -> Компилятор Java. Убедитесь, что настройки соответствия обновлены. У меня была эта проблема, когда параметры соответствия были установлены на 1,4 вместо 1,6