什么是Java序列化?

Java序列化是将Java对象转换为字节流的过程,以便在网络上传输、在文件中存储或在内存中保存。Java序列化可实现对象的持久化存储,即使应用程序关闭,对象也可以保留在内存中。

序列化特征

序列化是将内存中的对象转换成字节流的过程,以便在网络上传输或者持久化存储。
序列化可以跨平台使用,即不同编程语言可以对序列化数据进行解析和使用。
序列化过程中需要考虑对象的结构、属性等信息,以便在反序列化的时候能够正确地还原对象。

序列化机制

Java中的序列化机制:Java提供了Serializable接口和Externalizable接口,通过实现这两个接口,Java对象可以以二进制流的形式进行序列化和反序列化。
JSON序列化机制:JSON是一种轻量级的数据交换格式,支持序列化常见的数据类型,可以被多种编程语言解析和使用。
XML序列化机制:XML也是一种常见的序列化机制,支持序列化复杂的数据结构,但相对JSON而言,XML的解析和使用相对繁琐,性能也相对较低。
Protobuf序列化机制:Protobuf是Google开发的一种高效的数据序列化协议,具有压缩效率高、解析速度快等优点,被广泛应用于大规模数据序列化和网络传输场景。

为什么需要Java序列化?

Java序列化可用于在不同Java虚拟机之间传输对象。这对于分布式应用程序非常有用。另外,序列化还可以用于将Java对象保存在文件或数据库中。

如何使用Java序列化?

Java序列化需要实现Serializable接口。该接口是一个标记接口,不包含任何方法。只有实现了该接口的对象才能进行序列化和反序列化。

下面是一个Java序列化的示例代码:

import java.io.*;

public class SerializationDemo implements java.io.Serializable {
   public String name;
   public String address;
   public transient int SSN;
   public int number;

   public void mailCheck() {
      System.out.println("Mailing a check to " + name + " " + address);
   }
}

public class SerializeDemo {

   public static void main(String [] args) {
      SerializationDemo emp = new SerializationDemo();
      emp.name = "John Doe";
      emp.address = "123 Main St.";
      emp.SSN = 11122333;
      emp.number = 101;
      
      try {
         FileOutputStream fileOut =
         new FileOutputStream("/tmp/employee.ser");
         ObjectOutputStream out = new ObjectOutputStream(fileOut);
         out.writeObject(emp);
         out.close();
         fileOut.close();
         System.out.printf("Serialized data is saved in /tmp/employee.ser");
      } catch (IOException i) {
         i.printStackTrace();
      }
   }
}

public class DeserializeDemo {
   public static void main(String [] args) {
      SerializationDemo emp = null;
      try {
         FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
         ObjectInputStream in = new ObjectInputStream(fileIn);
         emp = (SerializationDemo) in.readObject();
         in.close();
         fileIn.close();
      } catch (IOException i) {
         i.printStackTrace();
         return;
      } catch (ClassNotFoundException c) {
         System.out.println("SerializationDemo class not found");
         c.printStackTrace();
         return;
      }
      System.out.println("Deserialized Employee...");
      System.out.println("Name: " + emp.name);
      System.out.println("Address: " + emp.address);
      System.out.println("SSN: " + emp.SSN);
      System.out.println("Number: " + emp.number);
   }
}

该示例代码中,SerializationDemo类实现了Serializable接口,SerializeDemo类将对象进行序列化,并将其保存在/ tmp / employee.ser文件中。DeserializeDemo类从文件中读取序列化的对象,并对其进行反序列化。

网络编程中Java序列化的应用

在网络编程中,Java序列化可以用于客户端和服务器之间的数据传递。以下是一个简单的示例代码:

服务器端代码:

import java.io.*;
import java.net.*;

public class Server {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            Socket socket = serverSocket.accept();
            ObjectOutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
            Person person = (Person) inStream.readObject();
            System.out.println("Received: " + person.toString());
            person.setAge(25);
            outStream.writeObject(person);
            System.out.println("Sent: " + person.toString());
            serverSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

客户端代码:

import java.io.*;
import java.net.*;

public class Client {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("localhost", 8888);
            ObjectOutputStream outStream = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream inStream = new ObjectInputStream(socket.getInputStream());
            Person person = new Person("Alice", 20);
            System.out.println("Sent: " + person.toString());
            outStream.writeObject(person);
            person = (Person) inStream.readObject();
            System.out.println("Received: " + person.toString());
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

其中,Person类是一个简单的JavaBean,用于存储人员信息:

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 void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Person{name=" + name + ",age=" + age + "}";
    }
}

运行前先在终端输入:

javac Server.java
javac Client.java

然后运行服务器和客户端代码:

java Server
java Client

输出结果如下:

Sent: Person{name=Alice,age=20}
Received: Person{name=Alice,age=20}
Sent: Person{name=Alice,age=25}

可以看到,客户端将一个Person对象序列化后发送给服务器,服务器接收到该对象并打印输出。然后服务器将该对象的年龄修改为25后,将修改后的Person对象序列化后返回给客户端,客户端接收到该对象并打印输出。

Where

Java序列化可在任何Java应用程序中使用,包括Web应用程序和桌面应用程序。

When

Java序列化可在需要将对象保存在文件或数据库中或在网络传输时使用。

How

实现Serializable接口并使用ObjectOutputStream和ObjectInputStream进行序列化和反序列化操作。

Java序列化和反序列化的表格

下面是Java序列化和反序列化的表格:

以上的表格列举了Java序列化和反序列化的一些特点和区别。在序列化过程中,需要使用 ObjectOutputStream 对象输出流将Java对象转化为字节流,而在反序列化过程中,需要使用 ObjectInputStream 对象输入流将字节流转换回Java对象。在序列化和反序列化过程中都可以重写相应的方法以实现自定义的序列化和反序列化逻辑。序列化和反序列化的顺序也需要保持一致,否则反序列化可能会出现异常。

总结

Java序列化是将Java对象转换为字节流的过程。它可用于在不同的Java虚拟机之间传输对象,或将Java对象保存在文件或数据库中。Java序列化需要实现Serializable接口,该接口是一个标记接口。序列化可以通过ObjectOutputStream和ObjectInputStream类实现。Java序列化是免费的,没有任何成本。

10-02 02:27