java 对象序列化中处理数组,核心在于让包含该数组的类实现 java.io.serializable 接口,jvm 会自动递归序列化数组元素。对于基本类型数组(如 int[]),直接按字节流写入;对于对象数组(如 string[]),则需确保数组内的每个元素也是可序列化的,否则抛出异常。

基本类型数组与对象数组的序列化差异是什么
基本类型数组在序列化时被视为一个整体块,直接存储其长度和内容,效率极高。而对象数组的序列化过程则是遍历数组,对每个引用类型的元素单独执行序列化逻辑。如果数组中包含不可序列化的对象,整个序列化操作将失败。

import java.io.*;
public class ArraySerializationDemo {
public static void main(String[] args) throws Exception {
// 准备数据:基本类型数组和对象数组
int[] basicArray = {1, 2, 3};
String[] objectArray = {"Hello", "World"};
// 封装到可序列化对象中
DataHolder holder = new DataHolder(basicArray, objectArray);
// 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(holder);
oos.close();
// 反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
DataHolder restored = (DataHolder) ois.readObject();
System.out.println("Basic: " + Arrays.toString(restored.basicArray));
System.out.println("Object: " + Arrays.toString(restored.objectArray));
}
}
class DataHolder implements Serializable {
int[] basicArray;
String[] objectArray;
public DataHolder(int[] basic, String[] object) {
this.basicArray = basic;
this.objectArray = object;
}
}
运行上述代码,控制台输出:
Basic: [1, 2, 3]
Object: [Hello, World]
这证明了 JVM 能够正确处理这两种数组。注意,DataHolder 必须实现 Serializable,且 String 本身已实现该接口,因此无需额外处理。
如何处理数组中的 null 元素或自定义序列化逻辑
当数组中存在 null 元素时,序列化机制会正常记录该位置为空引用,反序列化时恢复为 null,不会报错。若需控制序列化行为,例如跳过某些敏感字段或转换格式,可实现 writeObject 和 readObject 方法,但通常建议通过 transient 关键字或外部化接口 Externalizable 来处理更复杂的场景。
掌握 ES6+ 特性,包括 async/await、解构、扩展运算符、箭头函数、Promise、模块、迭代器、生成器以及函数式编程模式,编写简洁高效的 Java

import java.io.*;
public class NullArrayDemo {
public static void main(String[] args) throws Exception {
String[] arrayWithNull = {"A", null, "C"};
Container container = new Container(arrayWithNull);
// 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(container);
}
// 反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
try (ObjectInputStream ois = new ObjectInputStream(bais)) {
Container restored = (Container) ois.readObject();
System.out.println("Element 0: " + restored.arr[0]);
System.out.println("Element 1: " + restored.arr[1]);
System.out.println("Element 2: " + restored.arr[2]);
}
}
}
class Container implements Serializable {
String[] arr;
public Container(String[] arr) { this.arr = arr; }
}
预期结果:
Element 0: A
Element 1: null
Element 2: C
此示例验证了 null 值在序列化流中被正确保留。若使用 transient 修饰数组,则该数组不会被序列化,反序列化后变为 null 或默认值。
当数组元素为不可序列化对象时会发生什么
如果数组中包含未实现 Serializable 接口的对象,调用 writeObject 时会立即抛出 java.io.NotSerializableException。这是最常见的序列化错误之一。解决方法是确保所有数组元素所属的类都实现 Serializable,或者在序列化前将不可序列化对象转换为可序列化形式(如字符串或基本类型)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










