解决"未经检查的警告"在Java中避免使用@suppressWarnings

时间:2014-12-31 11:06:23

标签: java generics unchecked

这是试图改进我的代码问题。关于泛型和未经检查的警告;我知道@suppresswarnings注释。问题是我想用什么代码来压制它。请拿下以下代码。

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

执行此操作的编码方式是什么(不是注释)。在我发现的文档中 术语&#34;未经检查&#34;意味着编译器没有足够的类型信息来执行确保类型安全所必需的所有类型检查。但是,没有得到它。这对我来说似乎没问题:

void foo(Number n) {
    Short asShort = (Short) n; //OK
    T  asTypeWhichExtendsNumber = (T) n; // warning
}

附加。如果我想添加一个空的构造函数,是否有任何方法可以保持&#34; ZERO&#34;在元素?

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

2 个答案:

答案 0 :(得分:1)

将“insert”方法声明为采用类型T的参数,而不是Number。现在,调用者可以传递任何数字,而不仅仅是匹配类的T类型参数的数字,如果类型不匹配,您将在运行时获得ClassCastException。

答案 1 :(得分:1)

让我们看看有问题的代码,class声明:

public class NumericBox<T extends Number> implements Box<T>

所以我们有一些T extends Number。这可能是LongInteger等。但是某些特定在编译时定义类型。

现在你有了一个方法:

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”那么你将不得不处理后果。