案例代码请看目录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序列化?/序列化的优点?

  1. 数据持久化:通过序列化,可以将对象保存到磁盘文件中,以便稍后使用。
  2. 对象传输:通过序列化和反序列化,对象可以在网络上进行传输,实现远程方法调用(RMI)。
  3. 分布式计算:在分布式系统中,可以将对象序列化后在不同的节点之间进行传输。
  4. 缓存策略:序列化还可以用于缓存策略,将对象转换为字节流保存在缓存中,以提高读取速度。 

如何实现Java序列化?

在Java中实现序列化需要满足两个条件:

  • 让对象所属的类实现java.io.Serializable接口。
  • 使用ObjectOutputStream类将对象写入输出流,或使用ObjectInputStream类从输入流中读取对象。