Java反序列化返回空对象 自定义Serializable Database类读写问题排查
问题定位与修复方案
1. 最核心错误:read方法返回值逻辑错误
你写的read方法中,已经将读取到的序列化对象赋值给了obj变量,但方法最终固定返回null,相当于无论是否读取成功,拿到的结果都是空。
修复方式:将read方法最后一行的return null;改为return obj;。
2. read方法前置逻辑不合理
读取文件前你调用了temp.createNewFile(),如果对应路径的存储文件不存在,会直接创建一个空的.ser文件,紧接着读取空文件会触发EOFException,返回null,后续写入时如果对象本身是空的,就会一直恶性循环。
修复方式:读取前先判断文件是否存在且长度大于0,不存在时直接返回null即可,不要主动创建空文件,同时建议流操作改用try-with-resources语法,自动处理流关闭,避免资源泄漏:
public Object read() { Object obj = null; File temp = new File(this.filename); // 新增判断:文件不存在或者是空文件直接返回 if (!temp.exists() || temp.length() == 0) { return obj; } try (FileInputStream fileIn = new FileInputStream(this.filename); ObjectInputStream objectIn = new ObjectInputStream(fileIn)) { obj = objectIn.readObject(); System.out.println("The Object was successfully read from the file"); } catch (EOFException ex) { return obj; } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } return obj; }
3. 加载数据的调用逻辑存在隐患
你在loadData方法中直接用accommodationReviewsDatabase.read()调用读取方法,要是调用时这个变量还没初始化(值为null),会直接抛出空指针异常,就算没抛异常,未初始化对象的filename字段也可能是错的,导致读错文件。
修复方式:要么提前初始化所有Database子类实例,给filename字段赋正确的存储路径,要么将read方法改为静态方法,传入文件路径参数读取。
4. 序列化兼容校验
要确保所有Database子类都显式声明了serialVersionUID,否则JVM自动生成的UID会随着类结构变化而改变,导致之前序列化的文件无法读取,抛出异常。你可以在每个子类中加一行:
private static final long serialVersionUID = 1L;
如果类后续有不兼容旧数据的改动,再修改这个UID值即可。
内容的提问来源于stack exchange,提问作者laegil
相关产品推荐
相关产品推荐

