Java에서 직렬화의 개념은 무엇입니까?



이 기사는 더 나은 이해를 위해 실시간 예제와 함께 Java의 직렬화 개념에 대한 포괄적 인 접근 방식을 지원합니다.

직렬화 하나의 Java 가상 머신에서 다른 Java 가상 머신으로 Java 객체를 전송하고 원래 형태로 다시 생성하기 위해 객체를 바이트 스트림으로 변환하는 것을 다루는 중요한 개념입니다. 이 기사의 문서를 아래와 같이 정리하겠습니다.

Java에서 직렬화 란 무엇입니까?

직렬화 Java에서 Java 코드를 변환하는 프로세스입니다. 목적바이트 스트림 , 하나의 Java 가상 머신에서 다른 가상 머신으로 객체 코드를 전송하고 다음 프로세스를 사용하여 다시 생성합니다. 역 직렬화.





Serialization-in-Java-Edureka-Picture-1

직렬화가 필요한 이유 자바 ?

다음과 같은 이유로 직렬화가 필요합니다.



  • 통신 : 직렬화에는 객체의 절차가 포함됩니다. 직렬화전염. 이를 통해 여러 컴퓨터 시스템이 동시에 개체를 설계, 공유 및 실행할 수 있습니다.

  • 캐싱 : 객체를 만드는 데 걸리는 시간이 직렬화 해제에 필요한 시간에 비해 더 많습니다. 직렬화는 다음을 통해 시간 소비를 최소화합니다. 캐싱 거대한 물체.

  • 딥 카피 : 복제 Serialization을 사용하면 프로세스가 간단 해집니다. 정확한 레플리카 객체의객체 직렬화 바이트 배열 , 그리고 그것을 역 직렬화합니다.



  • 가로 질러 가다 JVM 동기화 : 직렬화의 가장 큰 장점은다른 JVM에서 실행될 수있는 다른 JVM에서 작동합니다. 아키텍처 또는 운영체제

  • 고집: 모든 객체의 State는 Serialization을 적용하여 직접 저장할 수 있으며 데이터 베이스 그것이 될 수 있도록 나중에 검색했습니다.

객체를 직렬화하는 방법은 무엇입니까?

자바 객체 이다 직렬화 가능 해당 클래스 또는 상위 클래스 중 하나가 자바 . 나는 . 직렬화 가능 인터페이스 또는 하위 인터페이스, java.io.Externalizable.

직렬화 프로세스에서 객체의 상태를 바이트 스트림으로 변환하여 한 JVM에서 다른 JVM으로 전송하고 바이트 스트림을 원래 객체로 되돌릴 수 있습니다.

//상호 작용

package Serial1 import java.io.Serializable public class Employee는 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 }}

// 직렬화

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 ( '직렬화 및 역 직렬화가 성공적으로 실행되었습니다')} catch (예외 e) {System.out.println (e)}}}

산출:

직렬화 및 역 직렬화가 성공적으로 실행되었습니다.

역 직렬화 : 송신자로부터 객체의 Serialized Byte Stream을 수신 측에서 다시 생성하는 Serialization의 역 과정입니다.

대학원 증명서는 무엇입니까

// 탈질 화

패키지 Serial1 import java.io. * class Depersist {public static void main (String args []) {try {ObjectInputStream in = new ObjectInputStream (new FileInputStream ( 'output.txt')) Employee e1 = (Employee) in.readObject ( ) Employee e2 = (Employee) in.readObject () Employee e3 = (Employee) 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 (예외 e) {System.out.println (e)}}}

산출:

20110 요한
22110 제리

20120 샘

Java에서 직렬화의 장단점

장점 :

  • 직렬화 프로세스는 내장 직렬화를 실행하기 위해 타사 소프트웨어가 필요하지 않은 기능
  • 직렬화 절차는 단순한쉬운 이해하다

  • 직렬화 절차는 만능인 배경이 다른 개발자도 익숙합니다.

  • 사용하기 쉽고 사용자 정의가 간단

  • 직렬화 된 데이터 스트림 암호화, 압축, 인증 지원안전한 자바 컴퓨팅

  • 많이있다 중요한 기술 직렬화에 의존합니다.

단점 :

  • DeSerialization이되는 동안 개체 다루기 힘든 그리고 그들은 효과적으로 DeSerialized 될지 확실하지 않습니다.

  • Serialization 동안 선언 된 Transient 변수는 메모리 공간을 생성하지만 생성자가 호출되지 않아 임시 변수 초기화에 실패하여 표준 Java Flow에 대한 변형.

  • 직렬화 과정은 무능한 메모리 활용 측면에서.

  • 직렬화는 필요한 응용 프로그램에서 사용하는 것이 바람직하지 않습니다. 동시 액세스 요구 사항없이 타사 API , Serialization은 모든 SE에 대한 전환 제어 메커니즘을 제공하지 않기 때문입니다.

  • 직렬화 절차를 제공하지 못함 세밀한 제어 개체에 액세스합니다.

Java에서 직렬화의 실제 예

상속을 사용한 직렬화

사례 – 1 : 수퍼 클래스가 직렬화 가능하면 기본적으로 해당 하위 클래스도 직렬화 가능합니다.

이 경우 아강 기본적으로 직렬화 가능합니다. 슈퍼 클래스 구현하고 있습니다 직렬화 가능한 인터페이스

패키지 SerializationInheritance import java.io.FileInputStream import java.io.FileOutputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.Serializable 클래스 A는 Serializable을 구현합니다 {int i public A (int i) {this.i = i}} 클래스 B 확장 A {int j public B (int i, int j) {super (i) this.j = j}} public class Test {public static void main (String [] args) throws 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 ( '객체가 직렬화되었습니다') FileInputStream fis = new FileInputStream ( 'abc.ser') ObjectInputStream ois = new ObjectInputStream (fis) B b2 = (B) ois.readObject () ois.close () fis.close () System.out.println ( '객체가 역 직렬화되었습니다') System.out.println ( 'i = '+ b2.i) System.out.println ('j = '+ b2.j)}}

산출:

j = 20
개체가 직렬화되었습니다.
개체가 역 직렬화되었습니다.
나는 = 200
j = 400

Salesforce의 앱은 무엇입니까

사례 – 2 : 수퍼 클래스가 직렬화 가능 인터페이스를 구현하지 않더라도 직렬화 가능 인터페이스를 구현하면 서브 클래스를 직렬화 할 수 있습니다.

이 경우 슈퍼 클래스 구현하지 않습니다 직렬화 가능한 인터페이스 , 그런 다음 아강 하위 클래스에서 직렬화 가능 인터페이스를 구현하여 수동으로 직렬화 할 수 있습니다.

패키지 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 called')}} class subclass extends superclass implementations Serializable {int j public subclass (int i, int j) {super (i) this.j = j }} public class test2 {public static void main (String [] args) throws 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 ( '객체가 직렬화되었습니다') FileInputStream fis = new FileInputStream ( 'output.ser') ObjectInputStream ois = new ObjectInputStream (fis) subclass b2 = (subclass) ois.readObject ( ) ois.close () fis.close () System.out.println ( '객체가 역 직렬화되었습니다') System.out.println ( 'i ='+ b2.i) System.out.println ( 'j =' + b2.j)}}

개체가 직렬화되었습니다.
슈퍼 클래스 생성자 호출
개체가 역 직렬화되었습니다.
나는 = 50
j = 20

사례 – 3 : 수퍼 클래스가 직렬화 가능하지만 직렬화 할 서브 클래스가 필요하지 않은 경우.

이 경우 하위 클래스의 직렬화를 방지 할 수 있습니다.구현함으로써 writeObject () readObject () 하위 클래스의 메서드와 NotSerializableException 이 방법에서.

패키지 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 Parent implementations Serializable {int i public Parent (int i) {this.i = i}} class child extends Parent {int j public child (int i, int j) {super (i) this.j = j} private void writeObject (ObjectOutputStream out) throws IOException {throw new NotSerializableException ()} private void readObject (ObjectInputStream in) throws IOException {throw new NotSerializableException ()}} public class test3 {public static void main (String [] args) throws 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 ( 'Object 직렬화되었습니다. ') FileInputStream fis = new FileInputStream ('abc.ser ') ObjectInputStream ois = new ObjectInputStream (fis) child b2 = (child) ois.readObject () ois.close () fis.close () System.out. println ( '객체가 역 직렬화되었습니다') System.out.println ( 'i ='+ b2.i) System.out.println ( 'j ='+ b2.j)}}

산출:

나는 = 100
j = 200
스레드 'main'java.io.NotSerializableException의 예외
SerializationInheritance.child.writeObject (test3.java:48)에서
sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)에서

정적 멤버를 사용한 직렬화

직렬화 과정에서 정적 멤버 필드의 직렬화는 무시됩니다. 직렬화는개체의 최신 상태와 관련이 있습니다. 따라서 클래스의 특정 인스턴스와 관련된 데이터 만직렬화되었지만 정적 멤버 필드는 아닙니다.

package stati import java.io. * class StaticSerial implements Serializable {static int i = 100 public static void main (String ... ar) {StaticSerial ob = new StaticSerial () System.out.println ( 'At the time of Serialization, 정적 멤버의 값 : '+ 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 ( 'Deserialization 후 정적 멤버는 다음 값을 갖습니다.' + i)} catch (예외 e) {System.out.println (e)}}}

산출:

직렬화시 정적 멤버의 값은 100입니다.
역 직렬화 후 정적 멤버의 값 : 99

외부화 가능한 인터페이스

그만큼 외부화 가능한 인터페이스 Java에서 직렬화와 유사하지만 유일한 차이점은 제공 할 수 있다는 것입니다. 맞춤형 직렬화 개울에 뿌려 질 물건을 결정하는 곳.

Externalizable 인터페이스는 java.io에서 사용할 수 있으며 두 가지 방법을 제공합니다.

  • public void writeExternal (ObjectOutput out) throws IOException
  • public void readExternal (ObjectInput in) throws IOException

Serialization과 Externalizeable의 주요 차이점은 다음과 같습니다.

  • 이행 : 사용자를 제외한 외부 인터페이스 명시 적으로 직렬화 할 개체를 언급합니다. 직렬화 인터페이스에있는 동안 모든 개체와 변수는 실행 시간.

  • 행동 양식 : 외부화 가능한 인터페이스는 두 가지 방법으로 구성됩니다.

    • writeExternal ()

    • readExternal ()

반면 Serializable Interface에는 메서드가 포함되어 있지 않습니다.

  • 이전 버전과의 호환성 및 제어 : Externalizable 인터페이스는 버전 관리 유일한 문제는 수퍼 클래스를 직렬화하는 동안 사용자가 책임을 져야한다는 것입니다. 반면에 직렬화 인터페이스에는 같은 버전 양쪽에 JVM이 있지만 수퍼 클래스를 포함한 모든 객체와 클래스의 자동 직렬화를 통합합니다.

  • 공개 No-Arg 생성자 : 외부화 인터페이스 요구 공개 No-Arg 생성자 직렬화 된 객체를 재구성합니다. 직렬화 인터페이스에는 No-Arg 생성자가 필요하지 않지만 대신 반사 직렬화 된 객체 또는 클래스를 재구성합니다.

package ext import java.io. * class Demo 구현 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 (filename) ObjectOutputStream out = new ObjectOutputStream (file) out .writeObject (object) out.close () file.close () System.out.println ( 'Object is been serialized')} catch (IOException ex) {System.out.println ( 'IOException is catch')} 데모 object1 = null try {FileInputStream file = new FileInputStream (filename) ObjectInputStream in = new ObjectInputStream (file) object1 = (Demo) in.readObject () in.close () file.close () System.out.println ( 'Object has been deserialized ') System.out.println ('a = '+ object1.a) System.out.println ('b = '+ object1.b)} catch (IOException ex) {System.out.println ('IOException이 catch되었습니다. ')} catch (ClassNotFoundException ex) {System.out .println ( 'ClassNotFoundException이 포착 됨')}}}

임시 키워드

임시 키워드는 예약 된 키워드 자바에서. 그것은 변수 수정 직렬화 프로세스시. Transient 키워드로 변수를 선언하면 변수가 직렬화되지 않습니다.

시리얼 버전 UID

직렬화 프로세스가 시작되기 전에 모든 직렬화 가능한 클래스 / 객체는 고유 식별 번호 호스트 머신의 JVM에서 제공합니다. 이 고유 ID는 시리얼 버전 UID . 이 UID는 수신 측에서 동일한 오브젝트가 DeSerialized되고 있음을 확인하기 위해 수신 측 JVM의 ID로 사용됩니다.

Java의 직렬화에 대한 논쟁

오라클 아키텍트는 Java에서 직렬화를 제거하려고합니다. 1997 년의 끔찍한 실수 . 바쁜 연구 끝에 Oracle의 개발자들은 데이터에 위협이되는 직렬화 절차 설계에서 몇 가지 결함을 발견했습니다.

1997 년에Mark Reinhold는“ 우리는 직렬화를 '지속적으로주는 선물'이라고 부르는 것을 좋아하는데, 그것이 계속해서주는 선물의 유형은 보안 취약점입니다. 아마도 모든 Java 취약점의 1/3이 직렬화와 관련되어 있으며 절반 이상일 수 있습니다. 불안정성은 말할 것도없고 놀랍도록 풍부한 취약점 소스입니다.”.

Java의 다가오는 업데이트에서 직렬화가 제거되거나 대체 될 가능성이 있으며 반면에 Java 초보자 인 경우 직렬화 할 수 없었다 이상주의적인 선택이되다 그들의 프로젝트에서

Java에서 직렬화를 사용하는 동안 모범 사례

다음은 따라야 할 몇 가지 모범 사례입니다.

  • 추천 사용입니다 javadoc @ 직렬화 가능 필드를 표시하기위한 직렬 태그.
  • 그만큼 .되려고 확장자는 직렬화 된 객체를 나타내는 파일에 사용되는 것이 좋습니다.
  • 정적 또는 일시적인 필드에는 권장되지 않습니다. 기본 직렬화.
  • 확장 가능한 클래스 그것이 아닌 한 직렬화해서는 안됩니다 필수.
  • 이너 클래스 직렬화에 관여하지 않아야합니다.

이것으로 우리는이 기사의 끝까지 왔습니다. Java에서 직렬화의 기본, 유형 및 기능을 이해 하셨기를 바랍니다.

확인 전 세계에 250,000 명 이상의 만족 한 학습자 네트워크를 보유한 신뢰할 수있는 온라인 학습 회사 인 Edureka에서 작성했습니다. Edureka의 Java J2EE 및 SOA 교육 및 인증 과정은 Java 개발자가 되고자하는 학생과 전문가를 위해 설계되었습니다. 이 과정은 Java 프로그래밍을 시작하고 Hibernate 및 같은 다양한 Java 프레임 워크와 함께 핵심 및 고급 Java 개념에 대해 교육하도록 설계되었습니다. .

질문이 있으십니까? 이 '자바 직렬화'기사의 주석 섹션에 언급하면 ​​가능한 한 빨리 답변을 드리겠습니다.