在java对象序列化读取过程中,`eofexception`并非异常情况,而是文件结束的正常信号;直接用`readobject()`返回值是否为`null`判断文件结尾是错误的,应改用数组整体序列化或捕获`eofexception`进行流程控制。
EOFException 是 ObjectInputStream.readObject() 在到达流末尾时主动抛出的受检异常,其设计本意就是作为“读取完成”的明确信号,而非程序错误。原代码中错误地假设 readObject() 会返回 null(类似 BufferedReader.readLine()),但 Java 序列化规范明确规定:该方法永远不会返回 null——成功时返回反序列化对象,失败时抛出异常(包括 EOFException、ClassNotFoundException、InvalidClassException 等)。
while ((lol = (Person) in.readObject()) != null) { // ⚠️ 永远不会进入循环体!
System.out.println(l
ol);
}此逻辑存在两个根本问题:
将整个对象数组一次性写入/读取,避免流边界不确定性:
// 写入端:替换原 for 循环
try (ObjectOutputStream out = new ObjectOutputStream(
new BufferedOutputStream(new FileOutputStream("object.txt")))) {
out.writeObject(people); // ← 直接写入整个数组
}
// 读取端:一次性读取并遍历
try (ObjectInputStream in = new ObjectInputStream(
new BufferedInputStream(new FileInputStream("object.txt")))) {
Person[] readPeople = (Person[]) in.readObject(); // ← 安全强转
for (Person p : readPeople) {
System.out.println(p);
}
}✅ 优势:无需处理流边界、无 EOFException 干扰、类型安全、性能更好(减少I/O调用次数)。
若必须逐个读取(如处理未知长度的流),应将 EOFException 视为“读取完成”标志,不打印堆栈也不视为错误:
try (ObjectInputStream in = new ObjectInputStream(
new BufferedInputStream(new FileInputStream("object.txt")))) {
while (true) {
try {
Person person = (Person) in.readObject();
System.out.println(person);
} catch (EOFException e) {
// ✅ 正常退出循环:文件读取完毕
break;
}
}
} catch (IOException | ClassNotFoundException e) {
// 其他异常才需真正处理(如文件损坏、类版本不匹配)
e.printStackTrace();
}通过采用数组整体序列化或合理利用 EOFException,即可彻底规避此类“意外异常”,让对象流操作既符合 Java 规范,又具备良好的可维护性与鲁棒性。