29

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

客户端代码:

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

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

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

谢谢,

路易斯

4

5 回答 5

22

尝试这个

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.
      }
    }
  }
}
于 2013-11-28T22:40:29.473 回答
15

无法避免此警告。readObject()返回一个对象。你需要投射它。并且转换为泛型类型总是会产生这样的警告。

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

于 2013-11-28T22:31:54.170 回答
2

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

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

并与之合作MyVariableList。这样,您就可以显式地向编译器提供足够的信息,以便在运行时进行类型检查。

于 2015-03-11T00:02:42.687 回答
2

我遇到了与 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<MyVariable> myList = Arrays.asList(myVarArr);

谢谢。

于 2018-04-25T01:31:05.183 回答
0

我也遇到了类似的情况,并且能够解决它。我的解决方案,适用于 OP 的例子是这样的:

myList = (ArrayList<Someclass>) Arrays.asList( (Someclass[]) ois.readObject() );

我已将命名约定(已经有人建议)更改为标准 Java(对象以小写字符开头),并且我已将 Class 重命名为MyVariable使其Someclass明确,这确实适用于任何类(而不仅仅是变量)。我还假设,myList服务器端类型的相应对象ArrayList<Someclass>已作为 Array 写入流Someclass[]。请注意,这很容易完成并且类似于 abhishek 已经建议的第一部分,但我的解决方案在最后一步有所不同:

  1. 我避免打电话Arrays.stream
  2. 它更容易阅读并被快速感知为简单的(没有进一步的逻辑)和checked(不产生警告)演员表。
于 2019-02-23T17:50:50.830 回答