Java 如何确保在序列化之前检查强制转换

Java 如何确保在序列化之前检查强制转换,java,Java,我已经构建了项目,并序列化了对象的ArrayList。它可以工作,但我知道它不能保证反序列化(读取)返回ArrayList。它可能会遇到ClassCastException在序列化或反序列化时如何执行安全类型检查 我提到: 但仍然困惑 非常感谢您的帮助 以下是我的部分代码: public void saveData() { if (playerList.size() != 0) { try { FileOutputStream fileOut

我已经构建了项目,并序列化了对象的ArrayList。它可以工作,但我知道它不能保证反序列化(读取)返回ArrayList。它可能会遇到
ClassCastException
在序列化或反序列化时如何执行安全类型检查

我提到:

  • 但仍然困惑

    非常感谢您的帮助

    以下是我的部分代码:

    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.");
        } 
    }
    
    以及加载时的代码

    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;
         }    
    }
    
    public void loadData(){
    试一试{
    FileInputStream fis=新的FileInputStream(“players.dat.ser”);
    ObjectInputStream ois=新ObjectInputStream(fis);
    ArrayList newPlayerList=(ArrayList)ois.readObject();//此处有警告
    setPlayerList(newPlayerList);
    ois.close();
    fis.close();
    }捕获(IOI异常){
    //i、 printStackTrace();
    返回;
    }捕获(NullPointerException n){
    //System.out.println(“无需恢复的数据”);
    //n、 printStackTrace();
    }捕获(ClassNotFoundException c){
    //System.out.println(“未找到players.dat文件”);
    //c、 printStackTrace();
    返回;
    }    
    }
    
    由于类型擦除,您可以通过
    instanceof
    说它是原始
    数组列表。不能对泛型类型参数执行任何检查

    如果您希望安全地执行此操作,那么您可以执行类似的操作,检查每一项并创建一个新列表,但这会带来开销

    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 }
        }
    }
    
    Object read=ois.readObject();
    List newPlayerList=newarraylist();
    如果(读取列表的实例){
    对于(对象项:(列表)读取){
    if(NimPlayer的项目实例){
    添加((NimPlayer)项);
    }
    //否则{可能引发异常或日志警告}
    }
    }
    

    否则,您可以抑制警告。

    在类
    NimPlayer
    中添加
    serialVersionUID
    。因此,这将确保反序列化仅加载具有相同
    serialVersionUID
    的arrayList,对吗?像一把钥匙@Sudhirojait没事了。如果我想使用
    ArrayList
    读回它,我需要使用
    Iterator
    添加回播放器,对吗?您不一定需要使用Iterator。我的示例使用for-each,它在引擎盖下使用了迭代器。但是,您也可以使用索引执行标准for循环。关键是,为了确保类型安全,您确实需要迭代,但迭代不一定涉及迭代器。我认为这个答案与这个问题中引用的一个问题的答案非常相似。美好的