Java - Serialização
Xin chào các nhà phép thuật Java tương lai! Hôm nay, chúng ta sẽ bắt đầu hành trình hấp dẫn vào thế giới Java Serialization. Đừng lo nếu bạn mới bắt đầu học lập trình – tôi sẽ là người hướng dẫn bạn thân thiện, và chúng ta sẽ làm theo từng bước. Khi hết hướng dẫn này, bạn sẽ kỹ năng serialize đối tượng như một chuyên gia!
Serialização là gì?
Trước khi chúng ta nhảy vào mã, hãy hiểu thế nào là serialização. Hãy tưởng tượng bạn có một bánh mì ngon (một đối tượng trong tiếng Java) mà bạn muốn gửi cho bạn của mình qua thư. Bạn không thể đặt toàn bộ bánh mì vào một chiếc phong bì, phải không? Thay vào đó, bạn sẽ cần phải phân hủy nó thành các nguyên liệu, viết chúng trên một tờ giấy, và gửi đi đó. Khi bạn của bạn nhận được, họ có thể tái tạo bánh mì bằng cách sử dụng hướng dẫn. Quá trình phân hủy một đối tượng thành một định dạng có thể lưu trữ hoặc truyền tải dễ dàng được gọi là serialização. Quá trình ngược lại – tái tạo đối tượng từ dữ liệu đã serialize – được gọi là deserialization.
Tại sao chúng ta cần Serialização?
Serialização rất hữu ích trong Java vì một số lý do:
- Lưu trữ trạng thái đối tượng: Bạn có thể lưu trữ trạng thái của một đối tượng và tái tạo nó sau này.
- Giao tiếp mạng: Bạn có thể gửi đối tượng qua mạng.
- Lưu trữ tạm: Các đối tượng đã serialize có thể được lưu trữ trong bộ nhớ cache để truy cập nhanh.
- Sao chép sâu: Cung cấp cách dễ dàng để tạo bản sao sâu của một đối tượng.
Bây giờ, hãy nhấc tay vào công việc mã!
Serialização hoạt động như thế nào trong Java
Trong Java, serialização được xây dựng vào ngôn ngữ, điều này làm cho cuộc sống của chúng ta dễ dàng hơn. Để làm một đối tượng serializable, chúng ta cần làm hai điều:
- Thực hiện giao diện
Serializable
- Đảm bảo tất cả các trường của đối tượng cũng serializable
Hãy tạo một lớp Person
đơn giản để minh họa:
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;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
Trong ví dụ này, Person
thực hiện Serializable
. Giao diện Serializable
không có bất kỳ phương thức nào – nó chỉ là một giao diện dấu chỉ để nói với Java lớp này có thể được serialize.
Serialize một đối tượng
Bây giờ, khi đã có lớp Person
, hãy serialize một đối tượng:
import java.io.*;
public class SerializationDemo {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
try (FileOutputStream fileOut = new FileOutputStream("person.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
out.writeObject(person);
System.out.println("Đối tượng Person đã serialize và lưu vào person.ser");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hãy phân tích:
- Chúng ta tạo một đối tượng
Person
. - Chúng ta sử dụng
FileOutputStream
để ghi vào một tệp có tên "person.ser". - Chúng ta gói
FileOutputStream
trong mộtObjectOutputStream
, điều này thực hiện serialize thực tế. - Chúng ta gọi
writeObject()
để serialize đối tượngPerson
của chúng ta. - Chúng ta sử dụng khối try-with-resources để đảm bảo các luồng của chúng ta được đóng đúng cách.
Khi bạn chạy điều này, nó sẽ tạo ra một tệp có tên "person.ser" chứa đối tượng Person
đã serialize.
Deserialize một đối tượng
Bây giờ, hãy deserialize đối tượng của chúng ta:
import java.io.*;
public class DeserializationDemo {
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("Đối tượng Person đã deserialize:");
System.out.println(person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Đây là điều gì đang diễn ra:
- Chúng ta sử dụng
FileInputStream
để đọc từ "person.ser". - Chúng ta gói nó trong một
ObjectInputStream
để deserialize. - Chúng ta gọi
readObject()
để deserialize đối tượng và ép kiểu nó thànhPerson
. - Chúng ta in ra đối tượng đã deserialize.
Khi bạn chạy điều này, bạn sẽ thấy đối tượng Person
gốc rễ được in ra!
Các điểm quan trọng về Serialização trong Java
-
SerialVersionUID: Để kiểm soát phiên bản của serialization, bạn có thể định nghĩa một
serialVersionUID
trong lớp của bạn:
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
// ... phần còn lại của lớp
}
-
Trường transient: Nếu bạn có các trường mà bạn không muốn serialize (như dữ liệu nhạy cảm), đánh dấu chúng là
transient
:
public class Person implements Serializable {
private String name;
private int age;
private transient String password; // Điều này sẽ không được serialize
// ... phần còn lại của lớp
}
-
Tùy chỉnh serialization: Bạn có thể tùy chỉnh quá trình serialization bằng cách thực hiện các phương thức
writeObject()
vàreadObject()
trong lớp của bạn.
Các phương thức cho Serializing và Deserializing một đối tượng
Dưới đây là bảng của các phương thức chính được sử dụng cho serialization và deserialization:
Phương thức | Mô tả |
---|---|
ObjectOutputStream.writeObject(Object obj) |
Serialize một đối tượng |
ObjectInputStream.readObject() |
Deserialize một đối tượng |
Externalizable.writeExternal(ObjectOutput out) |
Phương thức serialization tùy chỉnh |
Externalizable.readExternal(ObjectInput in) |
Phương thức deserialization tùy chỉnh |
Kết luận
Xin chúc mừng! Bạn vừa bước đi đầu tiên vào thế giới Java Serialization. Chúng ta đã bảo trì những gì là serialization, tại sao nó hữu ích, và làm thế nào để thực hiện trong Java. Nhớ rằng, luyện tập làm nên vĩ đại, vì vậy đừng sợ thử nghiệm với các đối tượng và tình huống khác nhau.
Khi tiếp tục hành trình Java của bạn, bạn sẽ tìm thấy serialization xuất hiện trong nhiều ngữ cảnh khác nhau – từ lưu trữ trạng thái trò chơi đến gửi dữ liệu qua mạng. Đó là một công cụ mạnh mẽ trong bộ công cụ lập trình của bạn.
Tiếp tục mã hóa, tiếp tục học hỏi, và nhất quan, tiếp tục vui chơi! Ai biết, có lẽ một ngày nào đó bạn sẽ serialize toàn bộ thế giới ảo. Đến khi đó, chúc mãi mãi mã hóa!
Credits: Image by storyset