logo

예제를 통한 Java의 직렬화 및 역직렬화

직렬화는 객체의 상태를 바이트 스트림으로 변환하는 메커니즘입니다. 역직렬화는 바이트 스트림을 사용하여 메모리에 실제 Java 개체를 다시 만드는 역 프로세스입니다. 이 메커니즘은 개체를 유지하는 데 사용됩니다. 직렬화-역직렬화-자바
생성된 바이트 스트림은 플랫폼 독립적입니다. 따라서 한 플랫폼에서 직렬화된 개체가 다른 플랫폼에서 역직렬화될 수 있습니다. Java 객체를 직렬화 가능하게 만들기 위해 우리는 다음을 구현합니다. java.io.직렬화 가능 상호 작용. ObjectOutputStream 클래스에는 다음이 포함됩니다. 쓰기객체() 객체를 직렬화하는 방법.

public final void writeObject(Object obj)  throws IOException>

ObjectInputStream 클래스에는 다음이 포함됩니다. 읽기객체() 객체를 역직렬화하는 방법.

public final Object readObject()  throws IOException,  ClassNotFoundException>

직렬화의 장점



자바의 디자인 패턴
  1. 객체의 상태를 저장/지속합니다.
  2. 네트워크를 통해 개체를 이동합니다.

구현하고 있는 클래스의 객체만 직렬화할 수 있습니다. java.io.직렬화 가능 상호 작용. 직렬화 가능은 마커 인터페이스 (데이터 멤버와 메소드가 없습니다). Java 클래스를 표시하여 이러한 클래스의 개체가 특정 기능을 얻을 수 있도록 하는 데 사용됩니다. 마커 인터페이스의 다른 예는 다음과 같습니다.- 복제 가능 및 원격.

기억해야 할 점

1. 상위 클래스가 직렬화 가능 인터페이스를 구현한 경우 하위 클래스는 이를 구현할 필요가 없지만 그 반대의 경우는 그렇지 않습니다.
2. 비정적 데이터 멤버만 직렬화 프로세스를 통해 저장됩니다.
3. 정적 데이터 멤버와 임시 데이터 멤버는 직렬화 프로세스를 통해 저장되지 않습니다. 따라서 비정적 데이터 멤버의 값을 저장하고 싶지 않다면 임시로 만드세요.
4. 객체가 역직렬화될 때 객체 생성자는 호출되지 않습니다.
5. 연관된 객체는 직렬화 가능 인터페이스를 구현해야 합니다. 예 :

class A implements Serializable{  // B also implements Serializable // interface. B ob=new B();  }>

SerialVersionUID 직렬화 런타임은 버전 번호를 SerialVersionUID라고 하는 각 직렬화 가능한 클래스와 연결합니다. 이 클래스는 직렬화된 개체의 보낸 사람과 받는 사람이 직렬화와 관련하여 호환되는 해당 개체에 대한 클래스를 로드했는지 확인하기 위해 직렬화 해제 중에 사용됩니다. 수신자가 해당 발신자의 클래스와 다른 UID를 가진 객체에 대한 클래스를 로드한 경우 Deserialization은 잘못된클래스예외 .

직렬화 가능 클래스는 필드 이름을 선언하여 자체 UID를 명시적으로 선언할 수 있습니다. 이는 static, final 및 long 유형이어야 합니다. 즉, ANY-ACCESS-MODIFIER static final long serialVersionUID=42L; 직렬화 가능 클래스가 serialVersionUID를 명시적으로 선언하지 않으면 직렬화 런타임은 Java 객체 직렬화 사양에 설명된 대로 클래스의 다양한 측면을 기반으로 해당 클래스에 대한 기본 버전을 계산합니다. 그러나 모든 직렬화 가능한 클래스는 serialVersionUID 값을 명시적으로 선언하는 것이 좋습니다. 해당 계산은 컴파일러 구현에 따라 달라질 수 있는 클래스 세부 사항에 매우 민감하기 때문에 클래스를 변경하거나 다른 ID를 사용하면 직렬화된 데이터에 영향을 미칠 수 있습니다. 또한 상속된 멤버로는 유용하지 않으므로 UID에는 전용 수정자를 사용하는 것이 좋습니다. 시리얼버 Serialver는 JDK와 함께 제공되는 도구입니다. Java 클래스의 serialVersionUID 번호를 가져오는 데 사용됩니다.

다음 명령을 실행하여 serialVersionUID serialver [-classpath classpath] [-show] [classname…]을 가져올 수 있습니다. 예시 1:

자바




// Java code for serialization and deserialization> // of a Java object> import> java.io.*;> class> Demo>implements> java.io.Serializable> {> >public> int> a;> >public> String b;> >// Default constructor> >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>, 'geeksforgeeks');> >String filename = 'file.ser';> > >// Serialization> >try> >{> >//Saving of object in a file> >FileOutputStream file =>new> FileOutputStream(filename);> >ObjectOutputStream out =>new> ObjectOutputStream(file);> > >// Method for serialization of object> >out.writeObject(object);> > >out.close();> >file.close();> > >System.out.println('Object has been serialized');> >}> > >catch>(IOException ex)> >{> >System.out.println('IOException is caught');> >}> >Demo object1 =>null>;> >// Deserialization> >try> >{> >// Reading the object from a file> >FileInputStream file =>new> FileInputStream(filename);> >ObjectInputStream in =>new> ObjectInputStream(file);> > >// Method for deserialization of object> >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 is caught');> >}> > >catch>(ClassNotFoundException ex)> >{> >System.out.println('ClassNotFoundException is caught');> >}> >}> }>

>

산성 특성

>

출력 :

Object has been serialized Object has been deserialized  a = 1 b = geeksforgeeks>

예시 2:

자바




// Java code for serialization and deserialization> // of a Java object> import> java.io.*;> class> Emp>implements> Serializable {> private> static> final> long> serialversionUID => >129348938L;> >transient> int> a;> >static> int> b;> >String name;> >int> age;> >// Default constructor> public> Emp(String name,>int> age,>int> a,>int> b)> >{> >this>.name = name;> >this>.age = age;> >this>.a = a;> >this>.b = b;> >}> }> public> class> SerialExample {> public> static> void> printdata(Emp object1)> >{> >System.out.println('name = ' + object1.name);> >System.out.println('age = ' + object1.age);> >System.out.println('a = ' + object1.a);> >System.out.println('b = ' + object1.b);> >}> public> static> void> main(String[] args)> >{> >Emp object =>new> Emp('ab',>20>,>2>,>1000>);> >String filename = 'shubham.txt';> >// Serialization> >try> {> >// Saving of object in a file> >FileOutputStream file =>new> FileOutputStream> >(filename);> >ObjectOutputStream out =>new> ObjectOutputStream> >(file);> >// Method for serialization of object> >out.writeObject(object);> >out.close();> >file.close();> >System.out.println('Object has been serialized '> >+ 'Data before Deserialization.');> >printdata(object);> >// value of static variable changed> >object.b =>2000>;> >}> >catch> (IOException ex) {> >System.out.println('IOException is caught');> >}> >object =>null>;> >// Deserialization> >try> {> >// Reading the object from a file> >FileInputStream file =>new> FileInputStream> >(filename);> >ObjectInputStream in =>new> ObjectInputStream> >(file);> >// Method for deserialization of object> >object = (Emp)in.readObject();> >in.close();> >file.close();> >System.out.println('Object has been deserialized '> >+ 'Data after Deserialization.');> >printdata(object);> >// System.out.println('z = ' + object1.z);> >}> >catch> (IOException ex) {> >System.out.println('IOException is caught');> >}> >catch> (ClassNotFoundException ex) {> >System.out.println('ClassNotFoundException' +> >' is caught');> >}> >}> }>

>

>

C의 2차원 배열 프로그램

산출:

Object has been serialized Data before Deserialization. name = ab age = 20 a = 2 b = 1000 Object has been deserialized Data after Deserialization. name = ab age = 20 a = 0 b = 2000>

출력 설명: 객체를 역직렬화하는 동안 a와 b의 값이 변경되는 것을 확인했습니다. a인 이유는 일시적인 것으로 표시되었고 b는 정적인 것으로 표시되었습니다.

다음의 경우 임시 변수:- 임시 키워드로 정의된 변수는 직렬화 과정에서 직렬화되지 않습니다. 이 변수는 역직렬화 중에 기본값으로 초기화됩니다. (예: 객체의 경우 null이고 int의 경우 0입니다.)

다음의 경우 정적 변수:- static 키워드로 정의된 변수는 직렬화 과정에서 직렬화되지 않습니다. 이 변수는 역직렬화 중에 클래스에 정의된 현재 값으로 로드됩니다.

일시적 대 최종:
결정적인 변수는 해당 값으로 직접 직렬화에 참여합니다.
따라서 최종 변수를 임시 변수로 선언해도 소용이 없습니다.
//컴파일러는 최종 변수에 값을 할당합니다.

예:

final int x= 10; int y = 20; System.out.println(x);// compiler will replace this as System.out.println(10)->x가 최종이기 때문에 10입니다. System.out.println(y);//20>

예시 3:

자바




//java code for final with transient> import> java.io.*;> class> Dog>implements> Serializable{> >int> i=>10>;> >transient> final> int> j=>20>;> }> class> GFG {> >public> static> void> main (String[] args)>throws> IOException,ClassNotFoundException> >{> >Dog d1=>new> Dog();> >//Serialization started> >System.out.println(>'serialization started'>);> >FileOutputStream fos=>new> FileOutputStream(>'abc.ser'>);> >ObjectOutputStream oos=>new> ObjectOutputStream(fos);> >oos.writeObject(d1);> >System.out.println(>'Serialization ended'>);> > >//Deserialization started> >System.out.println(>'Deserialization started'>);> >FileInputStream fis=>new> FileInputStream(>'abc.ser'>);> >ObjectInputStream ois=>new> ObjectInputStream(fis);> >Dog d2=(Dog) ois.readObject();> >System.out.println(>'Deserialization ended'>);> >System.out.println(>'Dog object data'>);> >//final result> >System.out.println(d2.i+>' '> +d2.j);> >}> }>

>

js 설정 시간 초과
>

산출

serialization started Serialization ended Deserialization started Deserialization ended Dog object data 10 20>