Question

beginner Java coder here. Here's the code:

private ArrayList<Rectangle> rectangles;
try {
        InputStream IS = MyClass.class.getResourceAsStream("file.dat");
        ObjectInputStream input = new ObjectInputStream(IS);
        rectangles = (ArrayList<Rectangle>) input.readObject();
} catch (IOException | ClassNotFoundException ex) {
        System.out.println(ex);
}

Netbeans tells me that this is an unchecked cast. Google tells me I should try to avoid this warning rather than suppress it, so how would I go about doing that? The only files that should be read by this program do indeed contain an ArrayList, and if not, I'm fine with just catching those exceptions.

Furthermore, if I do the same with with a char[][] (read it from and OIS and try to cast), netbeans doesn't have any problems with it. Why is that? I would think it's still an unchecked cast.

Was it helpful?

Solution

You should only suppress the warning if you know why it is there. In this case, since it sounds like you understand the issue and are taking steps to deal with it, then suppressing it is probably ok. If, however, you are hellbent on making the warning go away, the only method I have found to do that in this case is to do something like this:

public class ListOfRectangles extends ArrayList<Rectangle> {}

And then use ListOfRectangles as your data type for serializing to and from the file.

The reason the compiler is ok with char [] [] and not ArrayList<Rectangle> is because of a concept with Java generics known as erasure. It means that for generic types (like ArrayList) the parameterized type (Rectangle in this case) is not actually present in the bytecode. It is only there during compile-time so that the compiler can double-check your work. This is not the case with arrays.

There is a more in-depth look at generics here

OTHER TIPS

Sometimes it is simply impossible or way too difficult to avoid a cast. By any means try to avoid them by always assign checked types. But if you can't, then just suppress it. IMHO.

In this case looks perfectly legal to suppress it. It is better than returning an Object.

Always try to avoid this warning instead of suppressing it, that way it lowers the chances of a runtime error.

Avoid if possible, document if not. Here is the way that Josh Bloch recommends documenting it (Effective Java, 2nd ed, item 26):

private ArrayList<Rectangle> rectangles;
 try {
         InputStream IS = MyClass.class.getResourceAsStream("file.dat");
         ObjectInputStream input = new ObjectInputStream(IS);

         //The input stream is definitely an ArrayList<Rectangle>
         //I know this because...............
         @SuppressWarnings("unchecked")
         ArrayList<Rectangle> rectangles2 = (ArrayList<Rectangle>) input.readObject();
         rectangles = rectangles2;

 } catch (IOException | ClassNotFoundException ex) {
         System.out.println(ex);
}

This localizes the suppression to a couple lines of code, instead of the whole function.

It could be legitimate to suppress the warning. For example, if you are absolutely sure of the serialized format, you could suppress it.

However, if you are unsure, because someone else produced the serialized format, or you think the format might evolve over time, you can validate the contents without performing any unsafe casts.

List<?> untyped = (List<?>) input.readObject();
List<Rectangle> rectangles = new ArrayList<>(untyped.size());
for (Object obj : untyped)
  rectangles.add((Rectangle) obj);

This will ensure that if an element is not a Rectangle, the resulting ClassCastException will be thrown immediately, at the site of an explicit cast, instead of somewhere later, in a spot where no apparent cast is performed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top