+10

Serialization và Deserialization trong java - tại sao lại cần thiết

Trong lập trình Java, Serialization và Deserialization là hai khái niệm quan trọng giúp chuyển đổi đối tượng thành dạng dữ liệu có thể truyền và ngược lại. Đây không chỉ là một khía cạnh kỹ thuật quan trọng mà còn là một công cụ mạnh mẽ giúp xử lý và quản lý dữ liệu trong các ứng dụng phức tạp. Trong bài viết này, chúng ta sẽ khám phá lý do tại sao Serialization và Deserialization trở thành một phần quan trọng của phát triển Java và làm thế nào chúng đóng vai trò quan trọng trong các tình huống khác nhau

Serialization & Deserialization trong java

1. Khái niệm

  • Serialization đơn giản là quá trình chuyển đổi đối tượng Java thành dạng dữ liệu có thể truyền hoặc lưu trữ. Đối tượng sau khi được serialization trở thành một chuỗi byte, được gửi đi qua mạng hoặc lưu trữ vào file. Mảng byte này đại diện cho class của object, phiên bản của object, và trạng thái của object.

  • Deserialization Là quá trình chuyển đổi dữ liệu đã được serialization trở lại thành đối tượng Java. Dữ liệu được đọc từ nguồn như mạng hoặc file, sau đó được chuyển đổi thành đối tượng.

image.png

2. Đặc điểm của Serialization

  • Nếu superclassSerializable thì các lớp con của nó sẽ tự động được Serializable.
  • Khi bạn serialize bất kỳ object nào mà nó có chứa tham chiếu đến object khác thì Java serialization sẽ serialize luôn cả object đó (nếu object được tham chiếu không implement the java.io.Serializable interface thì java.io.NotSerializableException sẽ xảy ra
  • Bạn không thể serialize các biến static

3. Tại sao Serialization là cần thiết

Trong thế giới ngày nay, khi ứng dụng doanh nghiệp trở nên phức tạp và được triển khai trên nhiều hệ thống và mạng khác nhau, việc quản lý giao tiếp giữa các thành phần trở thành một thách thức đáng kể. Trong môi trường Java, nơi mọi thứ thường được biểu diễn dưới dạng các đối tượng, việc giao tiếp giữa hai thành phần Java đòi hỏi sự hiệu quả và tính linh hoạt cao.

Một phương pháp truyền thống để giao tiếp giữa các thành phần là xác định một giao thức riêng và chuyển đối tượng theo giao thức đó. Tuy nhiên, điều này đặt ra thách thức khi cần giao tiếp với các thành phần của bên thứ ba, vì đầu nhận cần phải biết giao thức cụ thể được sử dụng để có thể tái tạo đối tượng. Điều này gây khó khăn và phức tạp trong quá trình phát triển và bảo trì.

Để giải quyết vấn đề này, Serialization xuất hiện như một giải pháp chung và hiệu quả. Thay vì sử dụng các giao thức riêng lẻ, Serialization cung cấp một cơ chế chung để chuyển đối tượng giữa các thành phần Java. Giao thức này không chỉ đơn giản hóa quá trình truyền thông giữa các thành phần mà còn tăng cường tính tương thích và linh hoạt. Các thành phần có thể trao đổi dữ liệu mà không cần biết chi tiết về cách đối tượng được tái tạo, giảm độ phức tạp và tăng tính tái sử dụng.

Do đó, Serialization không chỉ là một phương tiện kỹ thuật, mà còn là một cơ sở cho việc xây dựng ứng dụng doanh nghiệp hiệu quả, có thể mượn dữ liệu từ nhiều nguồn khác nhau một cách dễ dàng và đồng nhất. Điều này giúp nâng cao khả năng tích hợp và tương tác giữa các thành phần, đồng thời tạo ra môi trường lập trình linh hoạt và dễ bảo trì.

  • Truyền Dữ Liệu Qua Mạng: Serializationcho phép đối tượng Java được chuyển đổi thành dạng dữ liệu có thể truyền qua mạng một cách dễ dàng. Điều này mở ra khả năng truyền thông tin giữa các máy chủ và máy khách, làm cho ứng dụng có khả năng tương tác qua mạng một cách linh hoạt.

  • Lưu Trữ Trạng Thái của Đối Tượng: Khi cần lưu trữ trạng thái của một đối tượng vào một file hoặc cơ sở dữ liệu, Serialization giúp chúng ta dễ dàng thực hiện điều này. Dữ liệu sau khi được serialization có thể được ghi vào file và sau đó được đọc và chuyển đổi thành đối tượng khi cần.

  • Chia Sẻ Dữ Liệu Giữa Các Ứng Dụng: Serialization là công cụ mạnh mẽ để chia sẻ dữ liệu giữa các thành phần khác nhau của một ứng dụng hoặc giữa các ứng dụng độc lập. Điều này giúp tạo ra các kiến trúc linh hoạt và dễ bảo trì.

  • RMI (Remote Method Invocation): Trong Java, RMI sử dụng Serialization để chuyển đối tượng giữa máy chủ và khách hàng trong mô hình phương thức từ xa. Điều này mang lại khả năng gọi phương thức từ xa một cách thuận tiện và hiệu quả.

    • Cho bạn nào chưa biết thì RMI, hay Remote Method Invocation, là một công nghệ trong ngôn ngữ lập trình Java được sử dụng để gọi các phương thức của đối tượng (objects) ở xa, tức là từ một máy tính có thể gọi các phương thức của một đối tượng đang chạy trên một máy tính khác. Điều này cho phép các ứng dụng Java tương tác và giao tiếp với nhau qua mạng
  • Duy Trì Trạng Thái Ứng Dụng: Serialization cung cấp khả năng duy trì trạng thái của ứng dụng, cho phép tạm dừng và tiếp tục thực thi mà không làm mất dữ liệu. Điều này có thể hữu ích trong nhiều tình huống, đặc biệt là khi ứng dụng phải xử lý các sự kiện không đồng đều.

3. SerialVersionUID là gì?

serialVersionUID là một trường (field) trong Java được sử dụng để định danh phiên bản của một lớp khi đối tượng của lớp đó được tuần tự hóa (serialized). Khi một đối tượng được tuần tự hóa, serialVersionUID được sử dụng để kiểm tra xem phiên bản của lớp hiện tại có tương thích với phiên bản đã tuần tự hóa hay không.

Nếu giá trị của serialVersionUID trên đối tượng đã tuần tự hóa không khớp với giá trị trên lớp đang chạy, Java sẽ thông báo một lỗi InvalidClassException, và việc đọc đối tượng từ dữ liệu tuần tự hóa sẽ thất bại.

image.png

Trong ví dụ này, serialVersionUID có giá trị là 123456789L. Nếu bạn muốn thay đổi cấu trúc lớp, bạn có thể cập nhật giá trị này.

4. Biến transient (tạm thời)

Biến transient trong Java được sử dụng để báo cho máy ảo Java (JVM) biết rằng nó không nên tuần tự hóa (serialize) giá trị của biến đó khi đối tượng được tuần tự hóa. Nó có ý nghĩa trong ngữ cảnh của tuần tự hóa và giải tuần tự hóa.

Khi một biến được đánh dấu là transient, giá trị của nó không sẽ không được bao gồm trong dữ liệu tuần tự hóa, và khi giải tuần tự hóa, giá trị của biến đó sẽ được thiết lập lại theo giá trị mặc định của kiểu dữ liệu của nó.

Ví dụ, giả sử bạn muốn tuần tự hóa một đối tượng Person, nhưng bạn không muốn lưu trữ mật khẩu của người đóng vai trò là một thuộc tính trong file tuần tự hóa. Bạn có thể đánh dấu mật khẩu là transient như sau:

image.png

Trong trường hợp này, khi bạn tuần tự hóa đối tượng Person, giá trị của password sẽ không được bao gồm trong dữ liệu tuần tự hóa. Khi giải tuần tự hóa, giá trị của password sẽ được thiết lập lại theo giá trị mặc định của kiểu dữ liệu String (null trong trường hợp này).

5. Tùy chỉnh tuần tự hóa (Externalizable Interface)

Externalizable Interface: Ngoài việc sử dụng Serializable interface, bạn cũng có thể sử dụng Externalizable interface để tùy chỉnh quá trình tuần tự hóa và giải tuần tự hóa theo cách riêng của mình. Điều này đòi hỏi việc triển khai các phương thức writeExternalreadExternal.

image.png

1. Một số điểm cần lưu ý về Externalizable:

  • Không có serialVersionID mặc định: Không có serialVersionUID mặc định, và do đó, nếu bạn không tự thiết lập, Java sẽ sử dụng một cách tính toán dựa trên cấu trúc lớp và có thể dẫn đến vấn đề về tương thích ngược.

  • Phải có constructor mặc định: Lớp cần phải có một constructor mặc định không tham số để JVM có thể tạo đối tượng trong quá trình giải tuần tự hóa.

  • Tùy chỉnh tất cả quá trình: Bạn có hoàn toàn quyền kiểm soát quá trình tuần tự hóa và giải tuần tự hóa. Điều này đặc biệt hữu ích khi bạn muốn thực hiện các xử lý đặc biệt hoặc chỉ tuần tự hóa một phần nhỏ của đối tượng.

2. Khi nào sử dụng Externalizable:

  • Khi bạn muốn có sự kiểm soát tối đa về quá trình tuần tự hóa và giải tuần tự hóa.
  • Khi bạn muốn tuần tự hóa hoặc giải tuần tự hóa chỉ một số trường cụ thể của đối tượng.
  • Khi hiệu suất là một yếu tố quan trọng và bạn muốn tối ưu hóa kích thước của dữ liệu tuần tự hóa

Tính linh hoạt và kiểm soát của Externalizable có thể làm cho nó trở thành lựa chọn hữu ích trong một số trường hợp, nhưng thường thì sử dụng Serializable là đủ để đáp ứng nhu cầu chung.

6. Kết luận

Nhìn chung, Serialization và Deserialization không chỉ là các khái niệm kỹ thuật mà còn là những công cụ mạnh mẽ giúp lập trình viên Java xử lý và quản lý dữ liệu một cách linh hoạt và hiệu quả. Từ khả năng truyền dữ liệu qua mạng đến khả năng lưu trữ và chia sẻ trạng thái của đối tượng, chúng đóng vai trò quan trọng trong quá trình phát triển ứng dụng.

Bài viết đã tìm hiểu về sự cần thiết của Serialization và Deserialization trong việc tạo ra các ứng dụng linh hoạt, dễ bảo trì và có khả năng tương tác qua mạng. Bằng cách tận dụng những khía cạnh này, lập trình viên có thể xây dựng các ứng dụng Java mạnh mẽ, đáp ứng được yêu cầu ngày càng đa dạng và phức tạp của thế giới công nghệ hiện đại. Điều này chứng minh rằng Serialization và Deserialization không chỉ là các khái niệm thuần kỹ thuật mà còn là những công cụ quan trọng giúp hình thành cơ sở hạ tầng của các ứng dụng Java hiện tại.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí