Here is a part of a program that sends an ArrayList from a server to a client. I want to remove the warning about the last line in this code:
Client code:
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 is a Java class with some attributes. The server is creating an ArrayList and filling it with MyVariable variables as items. Then it sends the complete list to the client.
I would like to know why do I have a warning there and how to code perfectly in order to have 0 warnings. If it is possible I would like to avoid using "@SuppressWarnings("unchecked")". ;)
Thank you,
Luis
Try this
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.
}
}
}
}
It's impossible to avoid this warning. readObject()
returns an Object. You need to cast it. And casting to a generic type will always generate such a warning.
If you want to make your code as clean as possible, which is a good idea, you should respect the Java naming conventions though, and make variable names start with a lowercase letter.
I don't like that, but you can have a container (sort of an alias or typedef):
// add "implements Serializable" in your case
private static class MyVariableList {
public List<MyVariable> value;
}
And work with MyVariableList
instead. That way you explicitly provide enough information to the compiler to do type checking in runtime.
I was running into a similar problem as OP and found a good solution with a combination of comment from @VGR and Java 1.8 method for Arrays.
I will provide my answer in terms of OP's question, so it is generic and hopefully helps others:
Instead of returning a collection (list), return an array from the server. Covert collection to an array using the following on the server side code:
myVariableList.toArray(new MyVariable[0]);
If performance is an issue with above, following could be used, so that array does not need to be resized:
myVariableList.toArray(myVariableList.size());
On client side convert array of object, to an array of MyVariable class.
This is specific to JAVA 8.
MyVariable[] myVarArr = Arrays.stream(ois.readObject()).toArray(MyVariable[]::new);
Then, finally convert Array to a Collection (list).
List<MyVariable> myList = Arrays.asList(myVarArr);
Thanks.