Workaround for unchecked cast of a deserialized Object to ArrayList
In general, the Java compiler knows the type of each variable, at every point during the execution. And when you operate on incompatible types, the program won't compile.

When you cast an object to ArrayList&lt;Vehicle&gt;, the Java runtime environment can only ensure that the cast to ArrayList&lt;something&gt; succeeds, but due to backwards compatibility (Java 1.4 from 2002), the cast will succeed, no matter if the arraylist contains Integer or String or Vehicle objects. Therefore, in this situation, the compiler warning tells you: Hey, you are doing something that cannot be checked, make sure you know what you are doing.

Your code that first deserializes the list as a raw type (ArrayList instead of ArrayList&lt;Vehicle&gt;) doesn't produce the compiler warning since the raw ArrayList is equivalent to ArrayList&lt;Object&gt;, and you won't get a surprising ClassCastException when working with this list.



If you are sure that the serialized list will only ever contain objects of type Vehicle, you can safely ignore that warning. In my code, I have written a utility function like this:

@SuppressWarnings("unchecked")
public static &lt;T&gt; T castToAnything(Object obj) {
    return (T) obj;
}

…

ArrayList&lt;Vehicle&gt; vehicles = castToAnything(in.readObject());


Another way is to not serialize the list, but to create a wrapper class:

public class SerializedData implements Serializable {
    public final ArrayList&lt;Vehicle&gt; vehicles = new ArrayList&lt;&gt;();
}


When you serialize this class and deserialize it, you still have to cast the type using (SerializedData) in.readObject(), but the warning goes away.

This still doesn't guarantee that the vehicles list contains only vehicles after deserialization, but that is an entirely different problem.