如何存储多List对象到文件?readObject用法及异常打印差异
Java对象序列化相关问题解答
1. 如何从文件中读取多个List对象?
要读取文件中的多个List对象,核心是利用对象序列化特性,通过ObjectInputStream循环读取,直到捕获EOFException(表示文件已读完所有对象)。前提是写入时需用ObjectOutputStream逐个写入每个List对象。
示例代码
写入多个List到文件
import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; public class WriteMultipleLists { public static void main(String[] args) { try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("lists.dat"))) { List<String> list1 = new ArrayList<>(); list1.add("Java"); list1.add("Python"); List<Integer> list2 = new ArrayList<>(); list2.add(10); list2.add(20); List<Double> list3 = new ArrayList<>(); list3.add(3.14); list3.add(2.71); // 逐个写入List对象 oos.writeObject(list1); oos.writeObject(list2); oos.writeObject(list3); System.out.println("多个List已写入文件"); } catch (Exception e) { e.printStackTrace(); } } }
从文件读取多个List
import java.io.FileInputStream; import java.io.ObjectInputStream; import java.util.List; public class ReadMultipleLists { public static void main(String[] args) { try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("lists.dat"))) { while (true) { try { Object obj = ois.readObject(); if (obj instanceof List) { System.out.println("读取到List: " + obj); } } catch (java.io.EOFException e) { // 捕获EOFException表示已读完所有对象,退出循环 break; } } System.out.println("所有List读取完成"); } catch (Exception e) { e.printStackTrace(); } } }
运行输出
多个List已写入文件 读取到List: [Java, Python] 读取到List: [10, 20] 读取到List: [3.14, 2.71] 所有List读取完成
2. 使用Object类对象读取字节流是否合理?
用Object接收readObject()的返回值是序列化读取的标准操作,但合理性取决于场景:
合理场景
- 明确知道写入的对象类型,后续可安全强制类型转换(比如读取多个已知类型的对象,如List、自定义类等)。
- 需要处理多种不同类型的对象,通过
instanceof判断类型后再做相应处理。
不合理场景
- 完全不清楚写入的对象类型,强制类型转换会抛出
ClassCastException,增加代码风险。 - 代码维护性差:若后续修改写入的对象类型,读取端的类型判断逻辑需同步更新,否则易出错。
示例代码(合理用法)
import java.io.FileInputStream; import java.io.ObjectInputStream; import java.util.List; public class ReadWithObject { public static void main(String[] args) { try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("lists.dat"))) { Object obj1 = ois.readObject(); if (obj1 instanceof List<?>) { List<?> list = (List<?>) obj1; System.out.println("读取到List: " + list); } Object obj2 = ois.readObject(); if (obj2 instanceof List<Integer>) { List<Integer> intList = (List<Integer>) obj2; System.out.println("整数List求和: " + intList.stream().mapToInt(Integer::intValue).sum()); } } catch (Exception e) { e.printStackTrace(); } } }
运行输出
读取到List: [Java, Python] 整数List求和: 30
3. 为何调用e.printStackTrace会显示EOFException,而调用e.getMessage却无异常输出?
核心原因:EOFException的无参构造函数不会设置异常消息,getMessage()返回null或空字符串;而printStackTrace()会打印异常类名和完整栈轨迹,不受消息是否为空的影响。
从JDK源码来看,EOFException的无参构造仅调用父类无参构造,此时detailMessage为null,所以getMessage()返回null,输出时看不到内容;但printStackTrace()会先打印异常类名,再输出栈信息,因此能看到异常。
示例代码
import java.io.EOFException; public class EOFExceptionDemo { public static void main(String[] args) { try { throw new EOFException(); } catch (EOFException e) { System.out.println("调用e.getMessage(): " + e.getMessage()); System.out.println("----------"); System.out.println("调用e.printStackTrace():"); e.printStackTrace(); } } }
运行输出
调用e.getMessage(): null ---------- 调用e.printStackTrace(): java.io.EOFException at EOFExceptionDemo.main(EOFExceptionDemo.java:6)
内容的提问来源于stack exchange,提问作者Abdullah
相关产品推荐
相关产品推荐

