初学者Java编码器。这是代码:
private ArrayList<Rectangle> rectangles;
try {
InputStream IS = MyClass.class.getResourceAsStream("file.dat");
ObjectInputStream input = new ObjectInputStream(IS);
rectangles = (ArrayList<Rectangle>) input.readObject();
} catch (IOException | ClassNotFoundException ex) {
System.out.println(ex);
}
Netbeans告诉我这是一个未经检查的演员。谷歌告诉我,我应该尽量避免这种警告,而不是压制它,那么我该如何去做呢?这个程序应该读取的唯一文件确实包含一个ArrayList,如果没有,我只是捕获这些异常。
此外,如果我使用char [] [](从OIS读取并尝试转换),netbeans没有任何问题。这是为什么?我认为它仍然是一个未经检查的演员。
答案 0 :(得分:2)
如果你知道它为什么,你应该只是压制警告。在这种情况下,因为听起来你理解这个问题并且正在采取措施来处理它,然后压制它可能没问题。但是,如果你对使警告消失感到沮丧,那么我在这种情况下发现的唯一方法就是做这样的事情:
public class ListOfRectangles extends ArrayList<Rectangle> {}
然后使用ListOfRectangles
作为数据类型,以便与文件进行序列化。
编译器使用char [] []
而不是ArrayList<Rectangle>
的原因是由于Java泛型称为擦除的概念。这意味着对于泛型类型(如ArrayList
),参数化类型(在本例中为Rectangle
)实际上并不存在于字节码中。它只在编译时才有,所以编译器可以仔细检查你的工作。数组不是这种情况。
对泛型here
有更深入的了解答案 1 :(得分:1)
有时候避免演员阵容根本不可能或太难。无论如何,总是通过分配检查类型来避免它们。但如果你不能,那就压制它吧。 IMHO。
在这种情况下看起来完全合法来压制它。这比返回Object
更好。
答案 2 :(得分:1)
始终尝试避免此警告而不是抑制它,这样可以降低运行时错误的可能性。
答案 3 :(得分:1)
尽可能避免,如果没有,请记录。这是Josh Bloch建议记录它的方式(Effective Java,2nd ed,item 26):
private ArrayList<Rectangle> rectangles;
try {
InputStream IS = MyClass.class.getResourceAsStream("file.dat");
ObjectInputStream input = new ObjectInputStream(IS);
//The input stream is definitely an ArrayList<Rectangle>
//I know this because...............
@SuppressWarnings("unchecked")
ArrayList<Rectangle> rectangles2 = (ArrayList<Rectangle>) input.readObject();
rectangles = rectangles2;
} catch (IOException | ClassNotFoundException ex) {
System.out.println(ex);
}
这将抑制本地化为几行代码,而不是整个函数。
答案 4 :(得分:0)
禁止警告可能是合法的。例如,如果您完全确定序列化格式,则可以禁止它。
但是,如果您不确定,因为其他人制作了序列化格式,或者您认为格式可能会随着时间的推移而发展,您可以验证内容而不执行任何不安全的演员表。
List<?> untyped = (List<?>) input.readObject();
List<Rectangle> rectangles = new ArrayList<>(untyped.size());
for (Object obj : untyped)
rectangles.add((Rectangle) obj);
这将确保如果一个元素不是Rectangle
,结果ClassCastException
将立即抛出,在显式演员的网站上,而不是稍后的某个地方,在一个没有明显的地方演员表演。