这是一个程序的一部分,它将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")"。)
谢谢你,
Luis
试试这个
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。你需要强制转换它。而强制转换为泛型类型总是会产生这样的警告。
如果您想使代码尽可能干净(这是一个好主意),那么您应该尊重Java命名约定,并使变量名以小写字母开头。
我遇到了一个与OP类似的问题,并找到了一个很好的解决方案,它结合了@VGR的注释和用于数组的Java 1.8方法。
我将根据OP的问题提供我的答案,因此它是通用的,希望能帮助其他人:
-
从服务器返回一个数组,而不是返回一个集合(列表)。在服务器端使用以下代码将收集隐蔽到阵列:
myVariableList.toArray(new MyVariable[0]);
如果性能是上面的问题,可以使用以下方法,这样阵列就不需要调整大小:
myVariableList.toArray(myVariableList.size());
-
在客户端,将对象的数组转换为MyVariable类的数组。
这是JAVA 8特有的。
MyVariable[] myVarArr = Arrays.stream(ois.readObject()).toArray(MyVariable[]::new);
-
然后,最后将Array转换为Collection(列表)。
List<MyVariable> myList = Arrays.asList(myVarArr);
谢谢。
我不喜欢这样,但你可以有一个容器(有点像别名或typedef):
// add "implements Serializable" in your case
private static class MyVariableList {
public List<MyVariable> value;
}
转而使用MyVariableList
。通过这种方式,您可以显式地向编译器提供足够的信息,以便在运行时进行类型检查。
我也遇到了类似的情况,并能够解决它。我的解决方案,应用于OP的例子是:
myList = (ArrayList<Someclass>) Arrays.asList( (Someclass[]) ois.readObject() );
我已经将命名约定(就像有人建议的那样)更改为标准Java(对象以小写字符开头),并将类MyVariable
重命名为Someclass
,以使其明确,这确实适用于任何类(而不仅仅是Variables)。我还假设,服务器端类型为ArrayList<Someclass>
的myList
的对应对象已作为Array Someclass[]
写入流中。注意,这很容易做到,类似于abhishek已经建议的第一部分,但我的解决方案在最后一步有所不同:
- 我避免打
Arrays.stream
- 它更容易阅读,并且可以快速感知为简单的(无需进一步的逻辑)和
checked
(不生成警告)投射