Woden
Woden

Reputation: 1386

How to ensure the cast checked before serialization

I've built the project and I serialized the ArrayList of objects. It works, but I know it cannot guarantee when deserializing (reading) back the ArrayList. It might encounter the ClassCastException How can I do the safe type check when serializing or deserializing?

I've referred to:

  1. Type safety: Unchecked cast from Object to ArrayList<MyVariable>
  2. How to perform a checked cast?

But still confused...

Any help is highly appreciated.

Here is part of my code:

public void saveData() {
    if (playerList.size() != 0) {
        try {
            FileOutputStream fileOut =
            new FileOutputStream("players.dat.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(playerList);
            out.close();
            fileOut.close();
            //System.out.printf("Serialized data is saved in players.dat.ser");
         } catch (IOException i) {
            i.printStackTrace();
         }

    } else {
        System.out.println("There is no data to be stored.");
    } 
}

And the code when loading back

public void loadData() {
    try {
        FileInputStream fis = new FileInputStream("players.dat.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        ArrayList<NimPlayer> newPlayerList = (ArrayList<NimPlayer>)ois.readObject();// warning here

        setPlayerList(newPlayerList);
        ois.close();
        fis.close();

     } catch (IOException i) {
        //i.printStackTrace();
        return;
     } catch (NullPointerException n) {
        //System.out.println("no data to be recoverd.");
        //n.printStackTrace();
     } catch (ClassNotFoundException c) {
        //System.out.println("players.dat file not found");
        //c.printStackTrace();
        return;
     }    
}

Upvotes: 1

Views: 190

Answers (1)

Michael
Michael

Reputation: 44230

Because of type erasure, the best you can say is that it's a raw ArrayList, via instanceof. You can't do any checks against the generic type parameter.

If you want to do it safely then you can do something like this, checking every single item and creating a new list, but there is an overhead involved.

Object read = ois.readObject();
List<NimPlayer> newPlayerList = new ArrayList<>();
if (read instanceof List) {
    for (Object item : (List<?>) read) { 
        if (item instanceof NimPlayer) {
            newPlayerList.add((NimPlayer) item);
        }
        // else { maybe throw exception, or log warning }
    }
}

Otherwise, you can suppress the warning.

Upvotes: 2

Related Questions