案例代码请看目录6.案例
1. 定义
Java序列化是将Java对象转换为字节序列以便存储或传输的过程。反序列化是将这些序列化的字节转换回Java对象的过程。Java中的对象序列化是对象持久性的一种实现方式,我们可以通过序列化将对象转换为字节,然后保存在文件或数据库中,也可以将对象序列化后通过网络进行传输,比如Java中的RMI(远程方法调用)。
2. 实现步骤
Java序列化的实现需要以下几个步骤:
(1)创建一个需要被序列化的Java对象,该对象需要实现 java.io.Serializable 接口。
(2)使用 ObjectInputStream 和 ObjectOutputStream 类,分别将 Java 对象进行序列化和反序列化。
(3)在使用反序列化时需要注意类的版本和兼容性问题。
3. 序列化原理
Java序列化的原理是通过将对象的数据结构和状态转换成字节流,将对象的类型和数据写入输出流中,然后将字节流传输给另一个设备或保存到存储介质中。反序列化的原理则是将字节流转换成对象的数据结构和状态,从而重构Java对象。
在序列化过程中,Java会对序列化的对象进行检查,如果发现该对象引用了其他对象,则会一同进行序列化并储存在输出流中。当对象的嵌套结构较为复杂时,在序列化过程中需要注意对象引用关系的处理,否则可能会引起序列化时出现错误或数据丢失的问题。
4. 序列化的注意点
在Java序列化的过程中,需要注意以下几点:
(1)序列化的类和属性必须是可序列化的,否则将会抛出 NotSerializableException 异常。
(2)Java 提供了 transient 关键字来排除某些属性不被序列化。
(3)序列化的对象的嵌套结构较为复杂时,需要注意对象引用关系的处理。
(4)在反序列化时,要注意类的版本和兼容性问题。
5. 序列化的应用
Java 序列化可以用于以下场景:
(1)将 Java 对象进行存储或传输,如将对象存储到文件或数据库中,或通过网络传输。
(2)支持Java RMI(远程方法调用)。
(3)实现对象的深度复制。
(4)为对象编写可重用模块,用于程序版本升级或跨平台编程。
总的来说,Java序列化是Java语言的一个强大的特性,它为Java语言提供了灵活、方便的数据序列化和传输方案,使得Java程序可以更加容易地管理和数据存储、远程传输等操作。
6.案例
定义一个需要被序列化的Java对象:
import java.io.Serializable;
public class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
对Java对象进行序列化:
import java.io.*;
public class SerializeDemo {
public static void main(String[] args) {
Person person = new Person("Tom", 25);
try {
FileOutputStream fileOut = new FileOutputStream("person.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(person);
out.close();
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
对Java对象进行反序列化:
import java.io.*;
public class DeserializeDemo {
public static void main(String[] args) {
try {
FileInputStream fileIn = new FileInputStream("person.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
Person person = (Person) in.readObject();
System.out.println("Name: " + person.getName());
System.out.println("Age: " + person.getAge());
in.close();
fileIn.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
以上代码的工作流程为:
- 在 SerializeDemo 中,首先创建一个需要被序列化的 Person 对象并写入到 person.ser 文件中。
- 然后,在 DeserializeDemo 中,我们将 person.ser 中的数据读取出来,并将其反序列化为 Person 对象,并最终输出这个对象的属性值
Java中如何阻止对象被序列化?
为了阻止Java对象被序列化,可以在类中使用transient
关键字修饰字段。被transient
修饰的字段将不会被序列化,而在反序列化时会被设置为默认值。
序列化版本号的作用是什么?
序列化版本号是Java序列化机制中用来识别序列化对象版本的唯一标识符。当进行反序列化时,会比较序列化对象的版本号和当前类的版本号,如果版本不一致,会抛出InvalidClassException
。通过显式声明和管理版本号,可以避免在序列化和反序列化中出现类不一致的问题。
为什么要使用Java序列化?/序列化的优点?
- 数据持久化:通过序列化,可以将对象保存到磁盘文件中,以便稍后使用。
- 对象传输:通过序列化和反序列化,对象可以在网络上进行传输,实现远程方法调用(RMI)。
- 分布式计算:在分布式系统中,可以将对象序列化后在不同的节点之间进行传输。
- 缓存策略:序列化还可以用于缓存策略,将对象转换为字节流保存在缓存中,以提高读取速度。
如何实现Java序列化?
在Java中实现序列化需要满足两个条件:
- 让对象所属的类实现
java.io.Serializable
接口。 - 使用
ObjectOutputStream
类将对象写入输出流,或使用ObjectInputStream
类从输入流中读取对象。