Java Serializable là gì? Serialization và Deserialization trong Java

Java Serializable là gì? Serialization và Deserialization trong Java.

Khi lập trình với Java chắc hẳn bạn đã bắt gặp khái niệm serialize nhất là khi đọc ghi object ra file, mapping với cơ sở dữ liệu…

Java Serializable là gì?

Serialization trong Java là cơ chế chuyển đổi trạng thái của một đối tượng (giá trị các thuộc tính trong object) thành một chuỗi byte sao cho chuỗi byte này có thể chuyển đổi ngược lại thành một đối tượng.

Quá trình chuyển đổi chuỗi byte thành đối tượng gọi là deserialization.

Một object có thể serializable (có thể thực hiện Serialization) nếu class của nó thực hiện implements interface java.io.Serializable

Tại sao cần Serialization?

Trong Java, khi trao đổi dữ liệu giữa các thành phần khác nhau (giữa các module cùng viết bằng Java) thì dữ liệu được thể hiện dưới dạng byte chứ không phải là đối tượng. Do đó ta cần có một cơ chế để hiểu các đối tượng được gửi và nhận.

Quá trình serilization hoàn toàn độc lập với platform (không phụ thuộc vào hệ điều hành) nên việc chuyển đổi giữa byte và object giữa các module được đảm bảo.

Code ví dụ

Ví dụ mình có 2 module, một module thực hiện chuyển đối tượng Customer thành byte và ghi ra file .Một module thực hiện đọc byte từ file và chuyển ngược lại thành đối tượng Customer.

(Trong thực tế thì 2 module có thể trao đổi qua database, network chứ không phải qua file)

package stackjava.com.serializable.demo;

import java.io.Serializable;

public class Customer implements Serializable{
  
  private static final long serialVersionUID = 1L;
  
  private int id;
  private String name;
  private transient String address;

  @Override
  public String toString() {
    return "Customer [id=" + id + ", name=" + name + ", address=" + address + "]";
  }

  // getter - setter

}
  • Đối tượng Customer sẽ gồm có 3 thuộc tính là id, name và address trong đó address được đánh dấu là transient tức là nó sẽ không được serialization.
  • private static final long serialVersionUID = 1L; để đảm bảo chắc chắn rằng đối tượng trước và sau khi serialization là một
package stackjava.com.serializable.demo;

import java.io.*;

public class WriteObjectDemo {
  
  public static void main(String[] args) throws FileNotFoundException, IOException {
    
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("src/customer.dat")));
    Customer customer = new Customer();
    customer.setId(1);
    customer.setName("kai");
    customer.setAddress("ha noi");
    
    System.out.println("Customer before serialization:");
    System.out.println(customer);
    oos.writeObject(customer);
    oos.close();
  }
}

Method writeObject() sẽ kiểm tra đối tượng được ghi có phải là serializable không, sau đó sẽ chuyển thành byte và thực hiện khi.

Kết quả:

Customer before serialization:
Customer [id=1, name=kai, address=ha noi]

Java Serializable là gì? Serialization và Deserialization trong Java

Tiếp theo mình thực hiện đọc dữ liệu từ file và chuyển thành đối tượng Customer.

package stackjava.com.serializable.demo;

import java.io.*;

public class ReadObjectDemo {
  
  public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("src/customer.dat")));
    System.out.println("Customer after deserialization:");
    Customer customer = (Customer) ois.readObject();
    System.out.println(customer);
    ois.close();
  }
}

Method readObject() sẽ chuyển byte thành đối tượng.

Vì mình ghi ra file dạng đối tượng Customer nên sau khi readObject() mình sẽ ép thành kiểu đối tượng Customer (Nếu bạn khi ra file dạng Map, List thì lúc đọc các bạn phải ép đúng kiểu tương ứng.

Kết quả:

Customer after deserialization:
Customer [id=1, name=kai, address=null]

Trường address là transient nên sau khi deserialization sẽ không có dữ liệu.

Một số lưu ý về Serialization trong Java

  • Nếu class cha implement Serializable thì các class con không cần thực hiện implement Serializablenữa
  • Các thuộc tính statictransient sẽ không được serialization
  • Hàm khởi tạo (constructor) sẽ không được gọi khi một đối tượng được deserialization
  • Khi thực hiện serialization một đối tượng thì tất cả các thuộc tính bên trong nó đều phải là serializable (áp dụng với các thuộc tính có kiểu đối tượng, ví dụ object Person có thuộc tính Address thì thuộc tính Address đó cũng phải implement Serializable nếu không sẽ bị lỗi java.io.NotSerializableException khi thực hiện serialization đối tượng person).

 

Okay, Done!

Download code ví dụ trên tại đây.

 

References:

https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html

stackjava.com