Решите "непроверенное предупреждение" в Java, избегая @supressWarning
Это попытка улучшить мой код вопроса. О дженериках и непроверенном предупреждении; Я знаю о @suppresswarning
аннотаций. Вопрос в том, что я должен кодировать, чтобы подавить его. Возьми, пожалуйста, следующий код.
public class NumericBox<T extends Number> implements Box<T> {
private T element;
public NumericBox(T element) {
this.element = element;
}
@Override public T getElement() {
return element;
}
public T insert(Number newElement) {
T oldElement = this.element;
this.element = (T) newElement; // warning("unchecked")
return oldElement;
}
}
Какой способ кодирования это сделать (не аннотации). В документах, которые я нашел, термин "непроверенный" означает, что у компилятора недостаточно информации о типе, чтобы выполнить все проверки типов, необходимые для обеспечения безопасности типов. Но не понимаю. Мне кажется, это нормально
void foo(Number n) {
Short asShort = (Short) n; //OK
T asTypeWhichExtendsNumber = (T) n; // warning
}
Extra. если я хочу добавить пустой конструктор, есть ли способ сохранить "ноль" в элементе?
NumeircBox<Short> o = new NumericBox<>(); // expectes 0 in the element
2 ответа
Давайте посмотрим на рассматриваемый код, ваш class
объявление:
public class NumericBox<T extends Number> implements Box<T>
Итак, у нас есть какой-то тип T
тот extends Number
, Это может быть Long
, Integer
и т.д. Но некоторые конкретные и определенные во время компиляции типа.
Теперь у вас есть метод:
public T insert(Number newElement) {
T oldElement = this.element;
this.element = (T) newElement;
return oldElement;
}
Что занимает некоторое Number
любого типа - ни специфического, ни определенного во время компиляции, и вы приводите его в T
, Это ClassCastException
жду, чтобы случиться.
final NumericBox<BigDecimal> box = new NumericBox<>();
box.insert(3);
final BigDecimal val = box.getElement(); <-- OOPS!
Нет способа избежать этого предупреждения, потому что компилятор показывает вам пример этого, у вас есть непроверенное приведение, которое может во время выполнения вызвать ClassCastException
, Компилятор моет руки этой строки.
Итак, чтобы решить вашу проблему, измените код на:
public T insert(T newElement) {
T oldElement = this.element;
this.element = (T) newElement;
return oldElement;
}
Так как генерики стираются во время компиляции, на самом деле нет никакого способа исправить этот хак. Если вы хотите гарантировать безопасность типов во время выполнения, вам нужно изменить подпись. Если вы хотите взять "любой старый Number
"Тогда вам придется иметь дело с последствиями.
Объявите метод "insert" как принимающий параметр типа T, а не Number. Прямо сейчас вызывающий может передать любой номер, а не только тот, который соответствует параметру типа T вашего класса, и вы получите ClassCastException во время выполнения, если тип не совпадает.