2014-12-31 2 views
2

Это Попытка улучшить мой код вопрос. О дженериках и непроверенном предупреждении; Я знаю об аннотации @suppresswarning. Вопрос , что я могу запрограммировать, чтобы подавить его. Возьмите, пожалуйста, следующий код.Решите «непроверенное предупреждение» на Java, избегая @supressWarning

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 
} 

Дополнительная информация. если я хочу добавить пустой конструктор, каким-либо образом сохранить элемент «ZERO» в элементе?

NumeircBox<Short> o = new NumericBox<>(); // expectes 0 in the element 
+0

Почему подпись метода не 'T insert (T newElement)'? –

+0

Представьте, что вы действительно хотите использовать метод только для NumericBoxes, а не для каждого поля, и этот метод должен получать Number, а не каждый T.Вероятно, мне нужно что-то изменить с помощью compareTo() – Manu

+0

Я искал сценарий для предупреждения, попробуйте представить, что вы действительно хотите подпись. При необходимости я меняю сценарий. – Manu

ответ

1

Давайте посмотрим на код в вопросе, ваша 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 любого типа - ни specfic ни определенное во время компиляции и вы принуждать его в 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», вам придется иметь дело с последствиями.

+0

Как и ваш ответ. Но позвольте мне спросить 2 вещи. Можно ли затем использовать Number (суперкласс моего общего типа по моему классу). Второй код (код OOPS) работает для меня, я пробовал его дважды (bigdecimal и short): S – Manu

+0

@manutero, немного неправильно прочитал ваш исходный код - обновил условие ошибки. Не понимайте свой первый пункт re 'Number'. –

+0

см. Исключение. О другом. Если у вас есть класс A , как вы используете S (суперкласс) по классу (например, в подписях метода). Надеюсь, что это правильный вопрос :) – Manu

1

Объявите метод «вставки» как принимающий параметр типа T, а не номер. В настоящий момент вызывающий может передать любое число, а не только тот, который соответствует параметру T-типа вашего класса, и вы получите исключение ClassCastException во время выполнения, если тип не совпадает.

Смежные вопросы