对象流处理可序列化对象,字节流仅搬运原始字节;对象流需包装字节流且要求Serializable接口,字节流直接操作文件系统,二者单位、异常、依赖及数据格式均不同。

对象流处理的是可序列化的对象结构
对象流(ObjectInputStream 和 ObjectOutputStream)不直接读写字节,而是基于底层字节流构建的高级封装。它要求操作的对象必须实现 Serializable 接口,内部通过 JVM 的序列化机制将对象的状态(包括字段值、类型信息、继承关系、甚至 transient 字段的特殊处理等)转换为平台无关的字节序列。这个过程不是简单复制内存布局,而是按规范生成带元数据的二进制格式——比如写入类名、字段描述符、对象图引用标记等。
字节流只做原始字节搬运
字节流(如 FileInputStream、FileOutputStream)是 IO 体系中最基础的一层,完全不关心数据含义。它只负责从文件、管道或数组中按顺序读取或写出单个字节或字节数组,不做任何解析、转换或结构校验。例如用 read(byte[]) 读 1024 字节,得到的就是原始的 1024 个 byte 值;用 write(int) 写一个整数,实际只写最低 8 位(即该整数对 256 取模的结果)。
关键行为差异体现在三方面
-
异常类型不同:对象流操作失败常抛
InvalidClassException、NotSerializableException或StreamCorruptedException,反映的是序列化语义问题;字节流多抛IOException或子类,仅表示 I/O 通道异常。 -
资源依赖方式不同:对象流必须包装一个已打开的字节流(如
new ObjectOutputStream(new FileOutputStream("a.obj"))),自身不能独立连接文件系统;而字节流节点类(如FileInputStream)可直接绑定文件路径并管理底层句柄。 -
数据可读性与兼容性不同:用十六进制编辑器打开对象流生成的文件,会看到大量非文本控制字节和类签名,无法人工识别内容;字节流写入的纯文本内容(如
"abc".getBytes())则可能部分可见,但二进制文件(如图片)同样不可读——区别在于对象流的“不可读”是设计使然,字节流的不可读只是因为没经过字符解码。
判断是否在用对象流,看构造和操作目标
如果代码中出现 new ObjectOutputStream(...) 或 new ObjectInputStream(...),且后续调用 writeObject() / readObject() 方法,那就是对象流;若只调用 write(int)、read()、write(byte[]) 等基础方法,哪怕参数是 String.getBytes(),也仍属于字节流范畴。对象流的本质,是把“对象”当成了数据单元;字节流始终以“字节”为唯一单位。











