Ошибка столкновения имени Java, метод имеет то же самое стирание, что и другой метод
У меня есть два класса следующим образом
Класс QueryResult:
public class QueryResult
{
...
public static List sortResults(boolean ascending, List<QueryResult> toSort)
{ ...
}
}
и класс CaseResult:
public class CaseResult extends QueryResult
{
...
public static List sortResults(boolean ascending, List<CaseResult> toSort)
{ ...
}
}
Я получаю следующую ошибку:
Конфликт имен: метод sortResults(boolean, List) типа CaseResult имеет такое же стирание, что и sortResults(boolean, List) типа QueryResult, но не скрывает его CaseResult.java
Я попробовал ответить на аналогичный вопрос: clash name generics, такое же стирание, но получил больше ошибок. Я думаю, что могу что-то неправильно понять, или эти ответы не подходят для моего случая.
Может ли кто-нибудь предоставить какие-либо решения или объяснить больше, чтобы помочь мне понять? Спасибо вам всем.
2 ответа
Согласно документации Java,
Если подкласс определяет статический метод с той же сигнатурой, что и статический метод в суперклассе, то метод в подклассе скрывает метод в суперклассе.
Различие между сокрытием статического метода и переопределением метода экземпляра имеет важные последствия:
- Версия переопределенного метода экземпляра, который вызывается, является той из подкласса.
- Версия скрытого статического метода, который вызывается, зависит от того, вызывается ли он из суперкласса или из подкласса.
Причина ошибки кроется в ответе Даршита Чокши. Однако, поскольку решение / альтернатива еще не опубликовано, попробуйте следующее:
Вы пытаетесь переопределить метод sortResults() таким образом, чтобы можно было сортировать списки с различными элементами. Однако при переопределении необходимо иметь одинаковую сигнатуру типа. Сигнатура в вашем случае выглядит аналогично, но поскольку элементы в List различаются - компилятор понимает, что List
Вместо переопределения, вместо этого измените оригинальный метод в суперклассе (в вашем случае, QueryResult), чтобы он мог обрабатывать любой тип элемента List. Вы можете использовать подстановочный знак для достижения этой цели:
public class QueryResult {
...
public <T> static List<T> sortResults(boolean ascending, List<T> toSort) {
...
}
}
Этот метод получает список и выводит тип элемента, назначая тип элемента параметру универсального типа T. Всякий раз, когда вы захотите обратиться к типу элемента в теле метода, вместо использования имени типа элемента (ранее QueryResult или CaseResult), теперь вместо этого вы должны использовать переменную универсального типа T.
Вы также можете установить дополнительные границы для этой переменной, если это необходимо (т. Е. Если элемент списка должен быть подтипом QueryResult, вы можете сказать, что
Еще один комментарий к вашему оригинальному коду. Будьте очень осторожны с использованием необработанных типов в новом универсальном коде - вы возвращаете список в виде необработанного типа: List без указания типа элемента списка, т.е. параметризованного типа: List
Вы можете узнать больше о необработанном типе и параметризованном типе, а также о подводных камнях использования необработанных типов, а также дополнительную информацию о захвате и границах подстановочных знаков в учебнике:
Effective Java, by Joshua Bloch
Section: Generics
Item 23: Don't use raw types in new code
Item 28: Use bounded wildcards to increase API flexibility