Khái niệm về Serialization trong Java là gì?



Bài viết này sẽ giúp có một cách tiếp cận toàn diện về khái niệm Tuần tự hóa trong Java cùng với các ví dụ thời gian thực để hiểu rõ hơn.

Serialization trong là một khái niệm quan trọng đề cập đến việc chuyển đổi các đối tượng thành một luồng byte để vận chuyển các đối tượng java từ Máy ảo Java này sang Máy ảo Java khác và tạo lại chúng về dạng ban đầu. Tôi sẽ xếp hàng cho bài viết này như sau:

Serialization trong Java là gì?

Serialization trong Java là quá trình chuyển đổi mã Java Vật thành một Luồng Byte , để chuyển Mã đối tượng từ một máy ảo Java này sang một máy ảo Java khác và tạo lại nó bằng quá trình Hủy công nghệ hóa.





Serialization-in-Java-Edureka-Picture-1

Tại sao chúng ta cần Serialization trong Java ?

Chúng tôi cần Serialization vì những lý do sau:



  • Giao tiếp : Serialization liên quan đến thủ tục của đối tượng tuần tự hóatruyền tải. Điều này cho phép nhiều hệ thống máy tính thiết kế, chia sẻ và thực thi các đối tượng đồng thời.

  • Bộ nhớ đệm : Thời gian tiêu tốn để xây dựng một đối tượng nhiều hơn so với thời gian cần thiết để hủy tuần tự hóa nó. Serialization giảm thiểu tiêu thụ thời gian bằng cách bộ nhớ đệm những vật thể khổng lồ.

  • Bản sao sâu : Nhân bản quy trình được thực hiện đơn giản bằng cách sử dụng Serialization. Chính xác bản sao của một đối tượng được lấy bởituần tự hóa đối tượng thành một mảng byte , và sau đó hủy tuần tự hóa nó.



  • Vượt qua Đồng bộ hóa JVM: Ưu điểm chính của Serialization là nóhoạt động trên các JVM khác nhau có thể đang chạy trên các kiến trúc hoặc là Các hệ điều hành

  • Sự bền bỉ: Trạng thái của bất kỳ đối tượng nào có thể được lưu trữ trực tiếp bằng cách áp dụng Serialization cho nó và được lưu trữ trong cơ sở dữ liệu để nó có thể truy xuất sau đó.

Làm thế nào để chúng ta Serialize một đối tượng?

ĐẾN Đối tượng Javacó thể nối tiếp nếu và chỉ khi lớp của nó hoặc bất kỳ lớp cha nào của nó triển khai java . Tôi . Serializable giao diện hoặc giao diện con của nó, java.io.Externalizable.

Trong quá trình Serialization, chúng tôi chuyển đổi trạng thái của một đối tượng thành một luồng byte để nó có thể được chuyển từ JVM này sang JVM khác và hoàn nguyên luồng byte trở lại đối tượng ban đầu.

// Giao diện

package Serial1 import java.io.Serializable public class Employee triển khai Serializable {private static final long serialVersionUID = 1L // Serial Version UID int id String name public Employee (int id, String name) {this.id = id this.name = name }}

// Tuần tự hóa

package Serial1 import java.io. * class Persist {public static void main (String args []) {try {Employee emp1 = new Employee (20110, 'John') Employee emp2 = new Employee (22110, 'Jerry') Employee emp3 = new Employee (20120, 'Sam') FileOutputStream fout = new FileOutputStream ('output.txt') ObjectOutputStream out = new ObjectOutputStream (fout) out.writeObject (emp1) out.writeObject (emp2) out.writeObject (emp3) out. flush () out.close () System.out.println ('Serialization và Deserialization được thực thi thành công')} catch (Exception e) {System.out.println (e)}}}

Đầu ra:

Serialization và Deserialization được thực hiện thành công

Hủy đăng ký : Đó là quá trình ngược lại của Serialization trong đó Serialized Byte Stream của một đối tượng từ người gửi được tạo lại ở đầu nhận.

// Deserialise

package Serial1 import java.io. * class Depersist {public static void main (String args []) {try {ObjectInputStream in = new ObjectInputStream (new FileInputStream ('output.txt')) Nhân viên e1 = (Nhân viên) in.readObject ( ) Nhân viên e2 = (Nhân viên) in.readObject () Nhân viên e3 = (Nhân viên) in.readObject () System.out.println (e1.id + '' + e1.name) System.out.println (e2.id + '' + e2.name) System.out.println (e3.id + '' + e3.name) in.close ()} catch (Exception e) {System.out.println (e)}}}

Đầu ra:

20110 John
22110 Jerry

20120 Sam

Ưu điểm và nhược điểm của Serialization trong Java

Ưu điểm:

  • Quá trình tuần tự hóa là một được xây dựng trong tính năng không yêu cầu phần mềm của bên thứ ba thực thi Serialization
  • Thủ tục Serialization được chứng minh là đơn giảndễ dàng hiểu

  • Thủ tục tuần tự hóa là phổ cập và các nhà phát triển từ các nền tảng khác nhau đã quen thuộc với nó

  • Nó rất dễ sử dụng và đơn giản để tùy chỉnh

  • Các luồng dữ liệu được tuần tự hóa hỗ trợ Mã hóa, Nén, Xác thựcđiện toán Java an toàn

  • Có nhiều công nghệ quan trọng dựa vào tuần tự hóa.

Nhược điểm:

  • Các đối tượng trong khi DeSerialization trở thành giòn và chúng không chắc đã được DeSerialized hiệu quả.

  • Các biến tạm thời được khai báo trong khi tuần tự hóa tạo ra không gian bộ nhớ, nhưng hàm tạo không được gọi, dẫn đến lỗi trong quá trình khởi tạo biến tạm thời dẫn đến biến thể đối với Luồng Java tiêu chuẩn.

  • Quá trình tuần tự hóa là không hiệu quả về việc sử dụng bộ nhớ.

  • Serialization không được ưu tiên sử dụng trong các ứng dụng cần truy cập đồng thời không có yêu cầu của API của bên thứ ba , vì Serialization không cung cấp bất kỳ cơ chế kiểm soát chuyển đổi nào cho mỗi SE.

  • Thủ tục tuần tự hóa không cung cấp kiểm soát chi tiết để truy cập Đối tượng.

Ví dụ thực tế về Serialization trong Java

Serialization Sử dụng Kế thừa

Trường hợp - 1: Nếu Superclass là Serializable, thì theo mặc định, Subclass của nó cũng có thể serializable.

Trong trường hợp này, lớp con có thể tuần tự hóa theo mặc định nếu lớp chồng đang thực hiện Giao diện có thể nối tiếp hóa

gói SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable class A thi hành Serializable {int i public A (int i) {this.i = i}} class B mở rộng A {int j public B (int i, int j) {super (i) this.j = j}} public class Test {public static void main (String [] args) ném Exception {B b1 = new B (200,400) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = new FileOutputStream ('abc.ser') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Đối tượng đã được tuần tự hóa') FileInputStream fis = new FileInputStream ('abc.ser') ObjectInputStream ois = new ObjectInputStream (fis) B b2 = (B) ois.readObject () ois.close () fis.close () System.out.println ('Đối tượng đã được giải hóa') System.out.println ('i = '+ b2.i) System.out.println (' j = '+ b2.j)}}

Đầu ra:

j = 20
Đối tượng đã được nối tiếp
Đối tượng đã được deserialized
i = 200
j = 400

Trường hợp - 2: Một Lớp con có thể được tuần tự hóa nếu nó triển khai Giao diện có thể tuần tự hóa ngay cả khi một Lớp con không triển khai Giao diện có thể tuần tự hóa.

Trong trường hợp này, nếu lớp chồng không thực hiện Giao diện có thể nối tiếp hóa , sau đó, các đối tượng của lớp con có thể được tuần tự hóa theo cách thủ công bằng cách triển khai Giao diện có thể hóa nối tiếp trong lớp con.

package SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable class superclass {int i public superclass (int i) {this.i = i} public superclass () {i = 50 System.out.println ('Superclass constructor được gọi là')}} lớp con của lớp mở rộng lớp cha triển khai Serializable {int j public subclass (int i, int j) {super (i) this.j = j }} public class test2 {public static void main (String [] args) ném Exception {subclass b1 = new subclass (10, 20) System.out.println ('i =' + b1.i) System.out.println ( 'j =' + b1.j) FileOutputStream fos = new FileOutputStream ('output.ser') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Đối tượng đã được tuần tự hóa') FileInputStream fis = new FileInputStream ('output.ser') ObjectInputStream ois = new ObjectInputStream (fis) subclass b2 = (subclass) ois.readObject ( ) ois.close () fis.close () System.out.println ('Đối tượng đã được giải mã hóa') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Đối tượng đã được nối tiếp
Hàm tạo siêu lớp được gọi
Đối tượng đã được deserialized
tôi = 50
j = 20

Trường hợp - 3: Nếu lớp cha có thể tuần tự hóa, nhưng chúng ta không cần lớp con được tuần tự hóa.

Trong trường hợp này, việc tuần tự hóa lớp con có thể được ngăn chặnbằng cách thực hiện writeObject () readObject () các phương thức trong lớp con và nó cần ném NotSerializableException từ các phương pháp này.

gói SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.IOException import java.io.NotSerializableException import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable class Pable i public Parent (int i) {this.i = i}} class child extension Parent {int j public child (int i, int j) {super (i) this.j = j} private void writeObject (ObjectOutputStream out) ném IOException {ném new NotSerializableException ()} private void readObject (ObjectInputStream in) ném IOException {throw new NotSerializableException ()}} public class test3 {public static void main (String [] args) ném Exception {child b1 = new child (100, 200) System.out.println ('i =' + b1.i) System.out.println ('j =' + b1.j) FileOutputStream fos = new FileOutputStream ('abc.ser') ObjectOutputStream oos = new ObjectOutputStream ( fos) oos.writeObject (b1) oos.close () fos.close () System.out.println ('Đối tượng đã được tuần tự hóa ') FileInputStream fis = new FileInputStream (' abc.ser ') ObjectInputStream ois = new ObjectInputStream (fis) child b2 = (child) ois.readObject () ois.close () fis.close () System.out. println ('Đối tượng đã được giải mã hóa') System.out.println ('i =' + b2.i) System.out.println ('j =' + b2.j)}}

Đầu ra:

i = 100
j = 200
Ngoại lệ trong luồng 'main' java.io.NotSerializableException
tại SerializationInheritance.child.writeObject (test3.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)

Serialization sử dụng một thành viên tĩnh

Việc tuần tự hóa trường thành viên tĩnh bị bỏ qua trong quá trình tuần tự hóa. Serialization làliên quan đến trạng thái mới nhất của đối tượng. Do đó, chỉ dữ liệu được liên kết với một phiên bản cụ thể của một lớp làđược tuần tự hóa nhưng không phải là trường Thành viên tĩnh.

package static import java.io. * class StaticSerial thực hiện Serializable {static int i = 100 public static void main (String ... ar) {StaticSerial ob = new StaticSerial () System.out.println ('Tại thời điểm Serialization, static member có giá trị: '+ i) try {FileOutputStream fos = new FileOutputStream (' F: File.ser ') ObjectOutputStream oos = new ObjectOutputStream (fos) oos.writeObject (ob) oos.close () i = 99 FileInputStream fis = new FileInputStream ('F: File.ser') ObjectInputStream ois = new ObjectInputStream (fis) ob = (StaticSerial) ois.readObject () ois.close () System.out.println ('Sau khi Deserialization, thành viên tĩnh có giá trị:' + i)} catch (Ngoại lệ e) {System.out.println (e)}}}

Đầu ra:

Tại thời điểm Serialization, thành viên tĩnh có giá trị: 100
Sau khi Deserialization, thành viên tĩnh có giá trị: 99

Giao diện ngoại vi

Các Giao diện ngoại vi trong Java tương tự như Serialization nhưng sự khác biệt duy nhất là nó có khả năng cung cấp tuần tự hóa tùy chỉnh nơi bạn có thể quyết định các đối tượng được gửi đến trong luồng.

Giao diện có thể ngoại hóa có sẵn trong java.io và nó cung cấp hai phương pháp:

  • public void writeExternal (ObjectOutput out) ném IOException
  • public void readExternal (ObjectInput in) ném IOException

Sự khác biệt chính giữa Serialization và Externalizable như sau:

  • Thực hiện : Giao diện có thể ngoại hóa không cho phép người dùng rõ ràng đề cập đến các đối tượng được tuần tự hóa. Khi ở trong Giao diện tuần tự hóa, tất cả các đối tượng và biến được tuần tự hóa trong thời gian chạy.

  • Phương pháp : Giao diện có thể ngoại hóa bao gồm hai phương pháp, đó là:

    • writeExternal ()

    • readExternal ()

Trong khi, Giao diện có thể nối tiếp hóa không bao gồm bất kỳ phương pháp nào.

  • Quá trình: Quy trình tuần tự hóa trong Giao diện có thể ngoại hóa cung cấp sự tùy biến đến quá trình tuần tự hóa. Nhưng, Giao diện tuần tự hóa sẽ cung cấp mặc định quá trình tuần tự hóa.

  • Khả năng tương thích và kiểm soát ngược: Giao diện có thể gắn ngoài hỗ trợ Serialization bất kể kiểm soát phiên bản và vấn đề duy nhất là người dùng phải có trách nhiệm trong khi tuần tự hóa Super Class. Mặt khác, Giao diện tuần tự hóa yêu cầu cùng một phiên bản của JVM ở cả hai đầu nhưng nó kết hợp tự động tuần tự hóa tất cả các đối tượng và lớp bao gồm cả lớp cha.

  • Công khai No-Arg Constructor: Nhu cầu giao diện bên ngoài Công cụ xây dựng No-Arg để tái tạo lại đối tượng được tuần tự hóa. Trong khi Giao diện tuần tự hóa không yêu cầu Khối mã lệnh No-Arg, thay vào đó nó sử dụng sự phản chiếu để xây dựng lại đối tượng hoặc lớp được tuần tự hóa.

package ext import java.io. * class Demo thực hiện java.io.Serializable {public int a public String b public Demo (int a, String b) {this.a = a this.b = b}} class Test {public static void main (String [] args) {Demo object = new Demo (1, 'Welcome to Edureka') String filename = 'file.ser' try {FileOutputStream file = new FileOutputStream (tên tệp) ObjectOutputStream out = new ObjectOutputStream (file) out .writeObject (object) out.close () file.close () System.out.println ('Object has been serialized')} catch (IOException ex) {System.out.println ('IOException is catch')} Demo object1 = null thử {FileInputStream file = new FileInputStream (tên tệp) ObjectInputStream in = new ObjectInputStream (tệp) object1 = (Demo) in.readObject () in.close () file.close () System.out.println ('Đối tượng đã được deserialized ') System.out.println (' a = '+ object1.a) System.out.println (' b = '+ object1.b)} catch (IOException ex) {System.out.println (' IOException bị bắt ')} catch (ClassNotFoundException ex) {System.out .println ('ClassNotFoundException bị bắt')}}}

Từ khóa thoáng qua

Từ khoá Tạm thời là một từ khóa dành riêng trong Java. Nó được sử dụng như một sửa đổi biến tại thời điểm của quá trình Serialization. Việc khai báo một biến với từ khóa Transient tránh cho biến không bị Serialized.

UID phiên bản nối tiếp

Trước khi quá trình tuần tự hóa bắt đầu, mọi lớp / đối tượng có thể tuần tự hóa được liên kết với số nhận dạng duy nhất được cung cấp bởi JVM của máy chủ. ID duy nhất này được gọi là UID phiên bản nối tiếp . UID này được sử dụng làm định danh bởi JVM của đầu nhận để xác nhận rằng cùng một đối tượng đang được DeSerialized ở đầu nhận.

Tranh cãi về tuần tự hóa trong Java

Của Oracle Các kiến ​​trúc sư có ý định loại bỏ Serialization khỏi Java vì họ coi nó như một Sai lầm khủng khiếp năm 1997 . Sau khi nghiên cứu hăng say, các nhà phát triển tại Oracle đã phát hiện ra một vài sai sót trong việc thiết kế quy trình Serialization gây ra mối đe dọa cho dữ liệu.

Vào năm 1997,Mark Reinhold tuyên bố - “ Chúng tôi gọi tuần tự hóa là 'món quà không ngừng trao tặng' và loại quà tặng mà nó tiếp tục tặng là lỗ hổng bảo mật. Có lẽ một phần ba trong số tất cả các lỗ hổng Java có liên quan đến việc tuần tự hóa nó có thể là hơn một nửa. Đó là một nguồn lỗ hổng đáng kinh ngạc, chưa kể đến sự bất ổn định. ”.

tổng hợp trong java là gì

Có khả năng Serialization sẽ bị xóa hoặc thay thế trong các bản cập nhật sắp tới của Java và mặt khác, đối với người mới bắt đầu sử dụng Java, Serialization không thể là một lựa chọn lý tưởng trong các dự án của họ

Các phương pháp hay nhất khi sử dụng Serialization trong Java

Sau đây là một số phương pháp hay nhất cần tuân theo

  • Nó được khuyến khích sử dụng javadoc @ thẻ nối tiếp để biểu thị các trường có thể sắp xếp theo thứ tự.
  • Các .được phần mở rộng được ưu tiên sử dụng cho các tệp đại diện cho các đối tượng được tuần tự hóa.
  • Không khuyến khích bất kỳ trường tĩnh hoặc trường tạm thời nào phải trải qua tuần tự hóa mặc định.
  • Các lớp học có thể mở rộng không nên được Serialized trừ khi nó bắt buộc.
  • Lớp bên trong nên tránh dính líu đến Serialization.

Với điều này, chúng ta đã đi đến phần cuối của bài viết này. Tôi hy vọng bạn đã hiểu những điều cơ bản về Serialization trong Java, các loại và chức năng của nó.

Kiểm tra của Edureka, một công ty học trực tuyến đáng tin cậy với mạng lưới hơn 250.000 người học hài lòng trải dài trên toàn cầu. Khóa đào tạo và cấp chứng chỉ về Java J2EE và SOA của Edureka được thiết kế cho sinh viên và các chuyên gia muốn trở thành Nhà phát triển Java. Khóa học được thiết kế để cung cấp cho bạn khởi đầu về lập trình Java và đào tạo bạn về cả khái niệm Java cốt lõi và nâng cao cùng với các khung Java khác nhau như Hibernate & Mùa xuân .

Có một câu hỏi cho chúng tôi? Hãy đề cập đến nó trong phần nhận xét của bài viết “Serialization trong Java” này và chúng tôi sẽ liên hệ lại với bạn trong thời gian sớm nhất.