类型安全:未选中从Object转换为ArrayList

以下是将ArrayList从服务器发送到客户端的程序的一部分。 我想删除有关此代码中最后一行的警告:

客户代码:

Socket s; (...) // A server is sending a list from the other side of the link. ois = new ObjectInputStream(s.getInputStream()); MyList = (ArrayList) ois.readObject(); 

MyVariable是一个具有一些属性的Java类。 服务器正在创建一个ArrayList并用MyVariable变量填充它作为项目。 然后它将完整列表发送给客户端。

我想知道为什么我会在那里发出警告以及如何完美编码以获得0警告。 如果有可能我想避免使用“@SuppressWarnings(”unchecked“)”。 ;)

谢谢,

路易斯

尝试这个

 Object obj = ois.readObject(); // Check it's an ArrayList if (obj instanceof ArrayList) { // Get the List. ArrayList al = (ArrayList) obj; if (al.size() > 0) { // Iterate. for (int i = 0; i < al.size(); i++) { // Still not enough for a type. Object o = al.get(i); if (o instanceof MyVariable) { // Here we go! MyVariable v = (MyVariable) o; // use v. } } } } 

避免这种警告是不可能的。 readObject()返回一个Object。 你需要施展它。 并且转换为generics类型将始终生成此类警告。

如果你想让你的代码尽可能干净,这是一个好主意,你应该尊重Java命名约定,并使变量名以小写字母开头。

我不喜欢这样,但你可以有一个容器(一种别名或typedef):

 // add "implements Serializable" in your case private static class MyVariableList { public List value; } 

而是使用MyVariableList 。 这样,您就可以向编译器明确提供足够的信息,以便在运行时进行类型检查。

我遇到了与OP类似的问题,并且发现了一个很好的解决方案,结合了来自@VGR的注释和用于数组的Java 1.8方法。

我将根据OP的问题提供我的答案,因此它是通用的,希望能帮助其他人:

  1. 而不是返回集合(列表),从服务器返回一个数组。 使用服务器端代码上的以下内容将集合隐藏到数组中:

    myVariableList.toArray(new MyVariable[0]);

    如果性能是上述问题,可以使用以下内容,以便不需要调整数组的大小:

    myVariableList.toArray(myVariableList.size());

  2. 在客户端将对象数组转换为MyVariable类的数组。

    这是JAVA 8特有的。

    MyVariable[] myVarArr = Arrays.stream(ois.readObject()).toArray(MyVariable[]::new);

  3. 然后,最后将Array转换为Collection(列表)。

    List myList = Arrays.asList(myVarArr);

谢谢。