문제

"객체 직렬화"란 무엇을 의미합니까?몇 가지 예를 들어 설명해 주시겠습니까?

도움이 되었습니까?

해결책

직렬화는 객체를 일련의 바이트로 변환하여 객체를 지속적으로 저장하거나 통신 링크를 통해 스트리밍 할 수 있도록 객체를 쉽게 저장할 수 있습니다. 그런 다음 바이트 스트림은 원래 물체의 복제본으로 변환 될 수 있습니다.

다른 팁

직렬화를 객체 인스턴스를 일련의 바이트 시퀀스로 변환하는 과정으로 생각할 수 있습니다 (구현에 따라 이진이거나 아닐 수도 있음).

예를 들어 한 JVM에서 다른 JVM으로 네트워크를 통해 한 객체 데이터를 전송하려는 경우 매우 유용합니다.

Java에서는 직렬화 메커니즘이 플랫폼에 내장되어 있지만 구현해야합니다. 직렬화 가능 객체를 직렬화 할 수있는 인터페이스.

속성을 과도 현상.

마지막으로 기본 메커니즘을 무시하고 직접 제공 할 수 있습니다. 이것은 일부 특별한 경우에 적합 할 수 있습니다. 이렇게하려면 하나를 사용합니다 자바의 숨겨진 기능.

직렬화되는 것은 클래스 정의가 아니라 객체 또는 내용의 "값"이라는 것을 알아야합니다. 따라서 방법은 직렬화되지 않습니다.

다음은 읽기를 용이하게하는 의견이있는 매우 기본적인 샘플입니다.

import java.io.*;
import java.util.*;

// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  { 

        // Create a sample object, that contains the default values.
        SerializationSample instance = new SerializationSample();

        // The "ObjectOutputStream" class has the default 
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream( 
                               // By using "FileOutputStream" we will 
                               // Write it to a File in the file system
                               // It could have been a Socket to another 
                               // machine, a database, an in memory array, etc.
                               new FileOutputStream(new File("o.ser")));

        // do the magic  
        oos.writeObject( instance );
        // close the writing.
        oos.close();
    }
}

이 프로그램을 실행할 때 "O.Ser"파일이 생성되며 뒤에서 무슨 일이 있었는지 알 수 있습니다.

우리가 값을 변경하면 : adoninteger 예를 들어 integer.max_value, 우리는 출력을 비교하여 차이가 무엇인지 확인할 수 있습니다.

다음은 그 차이를 정확하게 보여주는 스크린 샷입니다.

alt text

차이점을 발견 할 수 있습니까? ;)

Java Serialization에는 추가 관련 필드가 있습니다. SerialVersionUid 그러나 나는 이것이 이미 너무 길어서 그것을 덮을 수 없다고 생각합니다.

6 살짜리 질문에 대답하는 대담, Java를 처음 접하는 사람들을위한 매우 높은 수준의 이해 만 추가

직렬화 란 무엇입니까?

물체를 바이트 및 바이트로 변환하는 것 (사제화).

직렬화는 언제 사용됩니까?

우리가 개체를 지속하고 싶을 때. 우리가 JVM의 수명을 넘어서 개체가 존재하기를 원할 때.

실제 예 :

ATM : 계정 보유자가 ATM을 통해 서버에서 돈을 인출하려고 할 때, 철수 세부 사항과 같은 계정 보유자 정보는 직렬화되어 세부 사항이 사로화되어 작업을 수행하는 데 사용되는 서버로 전송됩니다.

Java에서 직렬화가 수행되는 방법.

  1. 구현하다 java.io.Serializable 인터페이스 (마커 인터페이스 따라서 구현 방법이 없음).

  2. 개체를 지속하십시오 : 사용하십시오 java.io.ObjectOutputStream 클래스, 하단 바이트 스트림 주변의 래퍼 인 필터 스트림 (파일 시스템에 객체를 작성하거나 네트워크 와이어를 통해 평평한 객체를 전송하고 다른 쪽에서 재건 됨).

    • writeObject(<<instance>>) - 물체를 씁니다
    • readObject() - 직렬화 된 객체를 읽습니다

기억하다:

객체를 직렬화하면 객체의 클래스 파일이나 메소드가 아니라 객체의 상태 만 저장됩니다.

2 바이트 객체를 직렬화하면 51 바이트 직렬화 된 파일이 표시됩니다.

물체가 직렬화되고 해제되는 방법 단계.

답변 : 51 바이트 파일로 어떻게 변환 했습니까?

  • 먼저 직렬화 스트림 매직 데이터 (stream_magic = "ac ed"및 jvm의 stream_version = 버전)를 씁니다.
  • 그런 다음 인스턴스 (클래스의 길이, 클래스의 이름, SerialversionUid)와 관련된 클래스의 메타 데이터를 작성합니다.
  • 그런 다음 슈퍼 클래스의 메타 데이터를 찾을 때까지 재귀 적으로 씁니다. java.lang.Object.
  • 그런 다음 인스턴스와 관련된 실제 데이터로 시작합니다.
  • 마지막으로 메타 데이터에서 실제 컨텐츠로 시작하는 인스턴스와 관련된 객체의 데이터를 씁니다.

Java Serialization에 대한 부서 정보에 더 관심이 있으시면이 확인을 확인하십시오. 링크.

편집하다 : 더 좋은 링크 읽다.

이것은 몇 가지 빈번한 질문에 답할 것입니다.

  1. 수업 시간에 필드를 연속화하지 않는 방법.
    ANS : 과도 키워드를 사용하십시오

  2. 아동 수업이 직렬화되면 부모 클래스가 직렬화됩니까?
    ANS : 아니요, 부모가 직렬화 가능한 인터페이스를 연장하지 않는 경우 부모 필드는 직렬화되지 않습니다.

  3. 부모가 직렬화되면 아동 계급이 직렬화됩니까?
    ANS : 그렇습니다. 기본적으로 아동 클래스도 직렬화됩니다.

  4. 아동 수업이 직렬화되는 것을 피하는 방법은 무엇입니까?
    ANS : a. WriteObject 및 readObject 메소드를 무시하고 던지십시오 NotSerializableException.

    비. 또한 아동 클래스에서 모든 필드를 일시적으로 표시 할 수 있습니다.

  5. 스레드, 출력 스트림 및 하위 클래스 및 소켓과 같은 일부 시스템 수준 클래스는 직렬화 할 수 없습니다.

직렬화는 메모리에서 "라이브"객체를 취하고 어딘가에 저장할 수있는 형식 (예 : 메모리, 디스크) 및 나중에 라이브 객체로 다시 "실시화 된"형식으로 변환합니다.

@oscarryz가 선물하는 방식이 마음에 들었습니다. 여기서도 계속하고 있습니다 직렬화 이야기 원래 @amitgupta가 작성했습니다.

로봇 클래스 구조에 대해 알고 직렬화 된 데이터 지구 과학자는 로봇을 작동시킬 수있는 데이터를 사로화 할 수 없었지만.

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

화성의 과학자들은 완전한 지불을 기다리고있었습니다. 지불이 완료되면 화성 과학자들이 SerialVersionUid 지구의 과학자들과 함께. 지구의 과학자는 그것을 로봇 클래스로 설정했고 모든 것이 잘되었습니다.

내 블로그에서 2 센트 :

다음은 직렬화에 대한 자세한 설명입니다: (내 자신의 블로그)

직렬화 :

직렬화는 물체의 상태를 지속하는 과정입니다. 바이트 시퀀스 형태로 표현되고 저장됩니다. 파일에 저장할 수 있습니다. 파일에서 객체의 상태를 읽고 복원하는 프로세스를 사제화라고합니다.

직렬화의 필요성은 무엇입니까?

현대 건축에서는 항상 객체 상태를 저장 한 다음 검색해야합니다. 예를 들어 최대 절전 모드에서 객체를 저장하려면 클래스를 직렬화 할 수 있어야합니다. 그것이하는 일은 일단 객체 상태가 바이트 형태로 저장되면 다른 시스템으로 전송 될 수 있으며 상태에서 읽고 클래스를 검색 할 수 있다는 것입니다. 객체 상태는 데이터베이스 또는 다른 JVM 또는 별도의 구성 요소에서 나올 수 있습니다. 직렬화의 도움으로 객체 상태를 검색 할 수 있습니다.

코드 예제 및 설명 :

먼저 항목 클래스를 살펴 보겠습니다.

public class Item implements Serializable{

    /**
    *  This is the Serializable class
    */
    private static final long serialVersionUID = 475918891428093041L;
    private Long itemId;
    private String itemName;
    private transient Double itemCostPrice;
    public Item(Long itemId, String itemName, Double itemCostPrice) {
        super();
        this.itemId = itemId;
        this.itemName = itemName;
        this.itemCostPrice = itemCostPrice;
      }

      public Long getItemId() {
          return itemId;
      }

     @Override
      public String toString() {
          return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
       }


       public void setItemId(Long itemId) {
           this.itemId = itemId;
       }

       public String getItemName() {
           return itemName;
       }
       public void setItemName(String itemName) {
            this.itemName = itemName;
        }

       public Double getItemCostPrice() {
            return itemCostPrice;
        }

        public void setItemCostPrice(Double itemCostPrice) {
             this.itemCostPrice = itemCostPrice;
        }
}

위의 코드에서는 볼 수 있습니다 안건 클래스 구현 직렬화 가능.

클래스를 직렬화 할 수있는 인터페이스입니다.

이제 우리는 변수가 호출되는 것을 볼 수 있습니다 SerialVersionUid 긴 변수로 초기화됩니다. 이 숫자는 클래스의 상태 및 클래스 속성을 기반으로 컴파일러에 의해 계산됩니다. 이것은 JVM이 파일에서 객체의 상태를 읽을 때 객체의 상태를 식별하는 데 도움이되는 숫자입니다.

이를 위해 공식 Oracle 문서를 볼 수 있습니다.

직렬화 런타임은 직렬화 가능한 클래스 A 버전 번호 (직렬화 된 객체의 발신자와 수신자가 직렬화와 관련하여 호환되는 해당 객체에 대한 클래스를로드했는지 확인하기 위해 삼각화 중에 사용되는 각 직렬화 가능한 클래스 A 버전 번호와 관련이 있습니다. 수신기가 해당 발신자 클래스의 클래스에 대한 클래스를로드 한 경우 해당 발신자 클래스의 클래스와 다른 직렬 버전이있는 클래스를로드 한 경우, 사형화로 인해 InvalidClassexception이 발생합니다. 직렬화 가능한 클래스는 정적, 최종 및 유형이어야하는 "SerialversionUid"라는 필드를 선언하여 자체 SerialVersionUid를 명시 적으로 선언 할 수 있습니다. 직렬화 가능한 클래스가 SerialversionUid를 명시 적으로 선언하지 않으면 Serialization 런타임은 Java (TM) 객체 직렬화 사양에 설명 된 바와 같이 클래스의 다양한 측면을 기반으로 해당 클래스의 기본 직렬 버전 값을 계산합니다. 그러나 기본 SerialversionUID 계산은 컴파일러 구현에 따라 달라질 수있는 클래스 세부 사항에 매우 민감하기 때문에 모든 직렬화 가능한 클래스가 직렬 버전 값 값을 명시 적으로 선언하는 것이 좋습니다. 따라서 다양한 Java 컴파일러 구현에서 일관된 SerialversionUid 값을 보장하기 위해 직렬화 가능한 클래스는 명시 적 SerialversionUID 값을 선언해야합니다. 또한 명시 적 SerialversionUid 선언은 가능한 경우 개인 수정자를 사용하는 것이 좋습니다. 이러한 선언은 즉시 선언하는 클래스에만 적용되므로 상속 된 구성원으로 유용하지 않기 때문입니다.

우리가 사용한 또 다른 키워드가 있음을 알게되면 과도 현상.

필드를 직렬화 할 수없는 경우 일시적으로 표시해야합니다. 여기서 우리는 ItemCostPrice 일시적이고 파일로 작성되기를 원하지 않습니다.

이제 파일에 객체의 상태를 작성하는 방법을 살펴보고 거기에서 읽으십시오.

public class SerializationExample {

    public static void main(String[] args){
        serialize();
       deserialize();
    } 

    public static void serialize(){

         Item item = new Item(1L,"Pen", 12.55);
         System.out.println("Before Serialization" + item);

         FileOutputStream fileOut;
         try {
             fileOut = new FileOutputStream("/tmp/item.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut);
             out.writeObject(item);
             out.close();
             fileOut.close();
             System.out.println("Serialized data is saved in /tmp/item.ser");
           } catch (FileNotFoundException e) {

                  e.printStackTrace();
           } catch (IOException e) {

                  e.printStackTrace();
           }
      }

    public static void deserialize(){
        Item item;

        try {
                FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
                ObjectInputStream in = new ObjectInputStream(fileIn);
                item = (Item) in.readObject();
                System.out.println("Serialized data is read from /tmp/item.ser");
                System.out.println("After Deserialization" + item);
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        } catch (IOException e) {
               e.printStackTrace();
        } catch (ClassNotFoundException e) {
               e.printStackTrace();
        }
     }
}

위에서 우리는 물체의 직렬화 및 사막화의 예를 볼 수 있습니다.

이를 위해 우리는 두 개의 클래스를 사용했습니다. 객체를 직렬화하기 위해 ObjectOutputStream을 사용했습니다. 우리는 writeObject 메소드를 사용하여 파일에 객체를 작성했습니다.

탈선하기 위해 파일에서 객체에서 읽는 ObjectInputStream을 사용했습니다. readObject를 사용하여 파일에서 객체 데이터를 읽습니다.

위 코드의 출력은 다음과 같습니다.

Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]

그것을주의해라 ItemCostPrice 사형화 된 대상으로부터 없는 쓰여지지 않았다.

우리는이 기사의 1 부에서 Java 직렬화의 기본 사항에 대해 이미 논의했습니다.

이제 그것을 깊이 논의하고 어떻게 작동하는지 논의합시다.

먼저 시작하겠습니다 SerialVersionUid.

그만큼 SerialVersionUid 직렬화 가능한 클래스에서 버전 컨트롤로 사용됩니다.

SerialversionUid를 명시 적으로 선언하지 않으면 Serializable 클래스의 다양한 속성을 기반으로 JVM이 자동으로 수행합니다.

SerialversionUid 계산에 대한 Java의 알고리즘 (자세한 내용은 여기를 참조하십시오)

  1. 클래스 이름.
    1. 클래스 수정자는 32 비트 정수로 작성되었습니다.
    2. 이름별로 정렬 된 각 인터페이스의 이름.
    3. 필드 이름으로 정렬 된 클래스의 각 필드에 대해 (개인 정적 및 개인 과도 필드 : 필드의 이름 제외. 필드의 수정자는 32 비트 정수로 작성되었습니다. 필드의 설명자.
    4. 클래스 이니셜 라이저가 존재하는 경우 다음을 기록하십시오. 메소드의 이름.
    5. 방법의 수정 자, java.lang.reflect.modifier.static, 32 비트 정수로 작성되었습니다.
    6. 방법의 설명자, () v.
    7. 메소드 이름과 서명으로 정렬 된 각 비 불안 생성자에 대해 : 메소드의 이름. 이 방법의 수정자는 32 비트 정수로 작성되었습니다. 방법의 설명자.
    8. 메소드 이름과 서명으로 정렬 된 각 비 불안 메소드에 대해 : 메소드 이름. 이 방법의 수정자는 32 비트 정수로 작성되었습니다. 방법의 설명자.
    9. SHA-1 알고리즘은 DataOutputStream에 의해 생성 된 바이트 스트림에서 실행되며 5 개의 32 비트 값 SHA [0..4]를 생성합니다. 해시 값은 SHA-1 메시지 다이제스트의 첫 번째 및 두 번째 32 비트 값에서 조립됩니다. 메시지 소화의 결과가 5 개의 32 비트 단어 H0 H1 H2 H3 H4가 SHA라는 5 개의 int 값의 배열에 있으면 해시 값은 다음과 같이 계산됩니다.
    long hash = ((sha[0] >>> 24) & 0xFF) |
>            ((sha[0] >>> 16) & 0xFF) << 8 |
>            ((sha[0] >>> 8) & 0xFF) << 16 |
>            ((sha[0] >>> 0) & 0xFF) << 24 |
>            ((sha[1] >>> 24) & 0xFF) << 32 |
>            ((sha[1] >>> 16) & 0xFF) << 40 |
>            ((sha[1] >>> 8) & 0xFF) << 48 |
>        ((sha[1] >>> 0) & 0xFF) << 56;

Java의 직렬화 알고리즘

객체를 직렬화하기위한 알고리즘은 다음과 같이 설명됩니다.
1. 인스턴스와 관련된 클래스의 메타 데이터를 기록합니다.
2. 그것은 그것을 찾을 때까지 슈퍼 클래스의 설명을 재귀 적으로 씁니다. java.lang.object.
3. 메타 데이터 정보 작성이 완료되면 인스턴스와 관련된 실제 데이터로 시작합니다. 그러나 이번에는 최상위 슈퍼 클래스에서 시작됩니다.
4. 최소한의 슈퍼 클래스에서 가장 파생 된 클래스로 시작하여 인스턴스와 관련된 데이터를 재귀 적으로 씁니다.

명심해야 할 사항 :

  1. 클래스의 정적 필드는 직렬화 될 수 없습니다.

    public class A implements Serializable{
         String s;
         static String staticString = "I won't be serializable";
    }
    
  2. SerialversionUid가 읽기 클래스에서 다른 경우 InvalidClassException 예외.

  3. 클래스가 직렬화 가능하면 모든 하위 클래스도 직렬화 할 수 있습니다.

    public class A implements Serializable {....};
    
    public class B extends A{...} //also Serializable
    
  4. 클래스에 다른 클래스의 참조가있는 경우 모든 참조는 직렬화 가능해야합니다. 그렇지 않으면 직렬화 프로세스가 수행되지 않습니다. 그러한 경우, NotserializableException 런타임에 던져집니다.

예 :

public class B{
     String s,
     A a; // class A needs to be serializable i.e. it must implement Serializable
}

직렬화는 Java의 지속적인 물체를 의미합니다. 객체의 상태를 저장하고 나중에 상태를 재건하려면 (다른 JVM에있을 수 있음) 직렬화를 사용할 수 있습니다.

객체의 속성은 저장 될 것입니다. 객체를 다시 부활 시키려면 멤버 변수가 저장되고 멤버 함수가 아닌 클래스 파일이 있어야합니다.

예 :

ObjectInputStream oos = new ObjectInputStream(                                 
                                 new FileInputStream(  new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();

searializable은 클래스가 직렬화 가능하다는 표시를하는 마커 인터페이스입니다. 마커 인터페이스는 비어있는 인터페이스 일 뿐이며 해당 인터페이스를 사용하면이 클래스가 직렬화 할 수 있음을 JVM에 알립니다.

직렬화는 하드 드라이브에 저장할 수 있도록 객체의 상태를 비트로 변환하는 과정입니다. 동일한 대상을 사로화하면 나중에 상태를 유지합니다. 객체의 속성을 손으로 저장하지 않고도 물체를 재현 할 수 있습니다.

http://en.wikipedia.org/wiki/serialization

직렬화는 스토리지 매체 (예 : 파일 또는 메모리 버퍼)에 객체를 저장하거나 이진 형태의 네트워크 연결을 통해 전송하는 프로세스입니다. 직렬화 된 객체는 JVM 독립적이며 모든 JVM에 의해 재 시로화 될 수 있습니다. 이 경우 "Memory"Java Objects 상태는 바이트 스트림으로 변환됩니다. 이 유형의 파일은 사용자가 이해할 수 없습니다. JVM (Java Virtual Machine)이 재사용 한 특수 유형의 객체 IE입니다. 객체를 직렬화하는이 과정을 객체 디플레이션 또는 마샬링이라고도합니다.

직렬화 할 객체는 구현해야합니다 java.io.Serializable 상호 작용. 객체에 대한 기본 직렬화 메커니즘은 객체의 클래스, 클래스 서명 및 모든 비-비-비 정적 필드의 값을 씁니다.

class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,

ObjectOutput 인터페이스를 확장합니다 DataOutput 객체를 직렬화하고 바이트를 작성하는 방법을 인터페이스하고 추가합니다. 그만큼 ObjectOutputStream 확장 java.io.OutputStream 그리고 구현 ObjectOutput 상호 작용. 객체, 어레이 및 기타 값을 스트림으로 직렬화합니다. 따라서 생성자 ObjectOutputStream 다음과 같이 작성되었습니다.

ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));

위의 코드는 인스턴스를 만드는 데 사용되었습니다. ObjectOutput 수업 ObjectOutputStream( ) 인스턴스를 취하는 생성자 FileOuputStream 매개 변수로.

그만큼 ObjectOutput 인터페이스는 구현하여 사용됩니다 ObjectOutputStream 수업. 그만큼 ObjectOutputStream 객체를 직렬화하도록 구성됩니다.

Java에서 물체를 사로화합니다

일련의 바이트에서 데이터를 추출하기 위해 직렬화의 반대 조작을 사제화라고합니다. 팽창 또는 unmarshalling이라고도하는 사제화라고도합니다.

ObjectInputStream 확장 java.io.InputStream 그리고 구현 ObjectInput 상호 작용. 입력 스트림에서 객체, 어레이 및 기타 값을 조정합니다. 따라서 생성자 ObjectInputStream 다음과 같이 작성되었습니다.

ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));

프로그램의 위의 프로그램은 인스턴스를 만듭니다. ObjectInputStream 클래스는 ObjectInputStream 수업. 위의 코드는 인스턴스를 사용하여 인스턴스를 만듭니다. FileInputStream 지정된 파일 개체를 보유하는 클래스는 ObjectInputStream() 생성자는 입력 스트림이 필요합니다.

자바 객체 직렬화

enter image description here

Serialization Java 객체의 그래프를 저장을 위한 바이트 배열로 변환하는 메커니즘입니다(to disk file) 또는 전송(across a network), 그런 다음 다음을 사용하여 역직렬화 객체의 그래프를 복원할 수 있습니다.참조 공유 메커니즘을 사용하여 개체 그래프가 올바르게 복원됩니다. 하지만 저장하기 전에 입력 파일/네트워크의 serialVersionUID와 .class 파일 serialVersionUID가 동일한지 확인하세요.그렇지 않다면 던져라. java.io.InvalidClassException.

버전이 지정된 각 클래스는 스트림을 쓸 수 있고 읽을 수 있는 원래 클래스 버전을 식별해야 합니다.예를 들어 버전이 지정된 클래스는 다음을 선언해야 합니다.

serialVersionUID 구문

// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L;
private static final long serialVersionUID = 3487495895819393L;

serialVersionUID 직렬화 프로세스에 필수적입니다.그러나 이를 Java 소스 파일에 추가하는 것은 개발자의 선택 사항입니다.serialVersionUID가 포함되지 않은 경우 직렬화 런타임은 serialVersionUID를 생성하고 이를 클래스와 연결합니다.직렬화된 객체에는 다른 데이터와 함께 이 serialVersionUID가 포함됩니다.

메모 - 직렬화 가능한 모든 클래스는 serialVersionUID를 명시적으로 선언하는 것이 좋습니다. since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, 따라서 deserialization 중에 예기치 않은 serialVersionUID 충돌이 발생하여 deserialization이 실패할 수 있습니다.

직렬화 가능 클래스 검사

enter image description here


Java 객체는 직렬화만 가능합니다.클래스나 해당 슈퍼클래스 중 하나가 다음 중 하나를 구현하는 경우 java.io.직렬화 가능 인터페이스 또는 그 하위 인터페이스, java.io.외부화 가능.

  • 클래스는 구현해야 합니다. java.io.직렬화 가능 인터페이스 객체를 성공적으로 직렬화하기 위해.직렬화 가능은 마커 인터페이스이며 이를 구현하는 클래스에 직렬화 가능 동작을 추가해야 함을 컴파일러에 알리는 데 사용됩니다. 여기서 JVM(Java Virtual Machine)은 자동 직렬화를 담당합니다.

    일시적인 키워드: java.io.Serializable interface

    객체를 직렬화하는 동안 객체의 특정 데이터 멤버가 직렬화되는 것을 원하지 않으면 임시 수정자를 사용할 수 있습니다.Transient 키워드는 해당 데이터 멤버가 직렬화되는 것을 방지합니다.

    • 임시 또는 정적으로 선언된 필드는 직렬화 프로세스에서 무시됩니다.

    과도 현상 & 휘발성 물질

    +--------------+--------+-------------------------------------+
    |  Flag Name   |  Value | Interpretation                      |
    +--------------+--------+-------------------------------------+
    | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.|
    +--------------+--------+-------------------------------------+
    |ACC_TRANSIENT | 0x0080 | Declared transient; not written or  |
    |              |        | read by a persistent object manager.|
    +--------------+--------+-------------------------------------+
    
    class Employee implements Serializable {
        private static final long serialVersionUID = 2L;
        static int id;
    
        int eno; 
        String name;
        transient String password; // Using transient keyword means its not going to be Serialized.
    }
    
  • 외부화 가능 인터페이스를 구현하면 객체가 객체의 직렬화된 형식의 내용과 형식을 완벽하게 제어할 수 있습니다.외부화 가능 인터페이스의 메소드인 writeExternal 및 readExternal이 호출되어 객체 상태를 저장하고 복원합니다.클래스에 의해 구현되면 ObjectOutput 및 ObjectInput의 모든 메서드를 사용하여 자체 상태를 쓰고 읽을 수 있습니다.발생하는 모든 버전 관리를 처리하는 것은 개체의 책임입니다.

    class Emp implements Externalizable {
        int eno; 
        String name;
        transient String password; // No use of transient, we need to take care of write and read.
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(eno);
            out.writeUTF(name);
            //out.writeUTF(password);
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.eno = in.readInt();
            this.name = in.readUTF();
            //this.password = in.readUTF(); // java.io.EOFException
        }
    }
    
  • java.io.Serialized 또는 java.io.Externalized 인터페이스를 지원하는 객체만 가능합니다. written to/read from 스트림.직렬화 가능한 각 객체의 클래스는 클래스 이름과 클래스 서명, 객체의 필드와 배열 값, 초기 객체에서 참조되는 다른 객체의 클로저를 포함하여 인코딩됩니다.

파일에 대한 직렬화 가능 예제

public class SerializationDemo {
    static String fileName = "D:/serializable_file.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        Employee emp = new Employee( );
        Employee.id = 1; // Can not Serialize Class data.
        emp.eno = 77;
        emp.name = "Yash";
        emp.password = "confidential";
        objects_WriteRead(emp, fileName);

        Emp e = new Emp( );
        e.eno = 77;
        e.name = "Yash";
        e.password = "confidential";
        objects_WriteRead_External(e, fileName);

        /*String stubHost = "127.0.0.1";
        Integer anyFreePort = 7777;
        socketRead(anyFreePort); //Thread1
        socketWrite(emp, stubHost, anyFreePort); //Thread2*/

    }
    public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
        FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );
        objectOut.writeObject( obj );
        objectOut.close();
        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            FileInputStream fis = new FileInputStream( new File( serFilename ) );
            ObjectInputStream ois = new ObjectInputStream( fis );
            Object readObject;
            readObject = ois.readObject();
            String calssName = readObject.getClass().getName();
            System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException

            Employee emp = (Employee) readObject;
            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
        FileOutputStream fos = new FileOutputStream(new File( serFilename ));
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        obj.writeExternal( objectOut );
        objectOut.flush();

        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            // create a new instance and read the assign the contents from stream.
            Emp emp = new Emp();

            FileInputStream fis = new FileInputStream(new File( serFilename ));
            ObjectInputStream ois = new ObjectInputStream( fis );

            emp.readExternal(ois);

            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

네트워크를 통한 직렬화 가능 예제

배포 개체동일한 컴퓨터의 서로 다른 프로세스 또는 네트워크를 통해 연결되어 있지만 데이터를 공유하고 메소드를 호출하여 함께 작동하는 여러 컴퓨터에서 서로 다른 주소 공간에 걸쳐 의 상태입니다.

/**
 * Creates a stream socket and connects it to the specified port number on the named host. 
 */
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
    try { // CLIENT - Stub[marshalling]
        Socket client = new Socket(stubHost, anyFreePort);
        ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
        out.writeObject(objectToSend);
        out.flush();
        client.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// Creates a server socket, bound to the specified port. 
public static void socketRead(  Integer anyFreePort ) {
    try { // SERVER - Stub[unmarshalling ]
        ServerSocket serverSocket = new ServerSocket( anyFreePort );
        System.out.println("Server serves on port and waiting for a client to communicate");
            /*System.in.read();
            System.in.read();*/

        Socket socket = serverSocket.accept();
        System.out.println("Client request to communicate on port server accepts it.");

        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Employee objectReceived = (Employee) in.readObject();
        System.out.println("Server Obj : "+ objectReceived.name );

        socket.close();
        serverSocket.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

@보다

직렬화는 Java 객체를 바이트 어레이로 전환 한 다음 보존 된 상태로 다시 물체로 돌아가는 과정입니다. 네트워크를 통해 객체를 보내거나 물건을 디스크로 캐싱하는 등 다양한 것들에 유용합니다.

더 많이 읽으십시오 프로세스의 일부를 프로그래밍하는이 짧은 기사 그런 다음 이동하십시오 직렬화 가능한 Javadoc. 당신은 또한 읽기에 관심이있을 수 있습니다 이 관련 질문.

파일을 객체로 반환합니다. http://www.tutorialspoint.com/java/java_serialization.htm

        import java.io.*;

        public class SerializeDemo
        {
           public static void main(String [] args)
           {
              Employee e = new Employee();
              e.name = "Reyan Ali";
              e.address = "Phokka Kuan, Ambehta Peer";
              e.SSN = 11122333;
              e.number = 101;

              try
              {
                 FileOutputStream fileOut =
                 new FileOutputStream("/tmp/employee.ser");
                 ObjectOutputStream out = new ObjectOutputStream(fileOut);
                 out.writeObject(e);
                 out.close();
                 fileOut.close();
                 System.out.printf("Serialized data is saved in /tmp/employee.ser");
              }catch(IOException i)
              {
                  i.printStackTrace();
              }
           }
        }

    import java.io.*;
    public class DeserializeDemo
    {
       public static void main(String [] args)
       {
          Employee e = null;
          try
          {
             FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn);
             e = (Employee) in.readObject();
             in.close();
             fileIn.close();
          }catch(IOException i)
          {
             i.printStackTrace();
             return;
          }catch(ClassNotFoundException c)
          {
             System.out.println("Employee class not found");
             c.printStackTrace();
             return;
          }
          System.out.println("Deserialized Employee...");
          System.out.println("Name: " + e.name);
          System.out.println("Address: " + e.address);
          System.out.println("SSN: " + e.SSN);
          System.out.println("Number: " + e.number);
        }
    }

|*| 클래스 직렬화 : 객체를 바이트 및 바이트로 변환 (사제화).

class NamCls implements Serializable
{
    int NumVar;
    String NamVar;
}

| => 객체-실현은 물체의 상태를 바이트의 증기로 변환하는 과정입니다.

  • |-> 객체가 JVM의 수명을 넘어 존재하기를 원할 때 구현하십시오.
  • |-> 직렬화 된 객체는 데이터베이스에 저장할 수 있습니다.
  • |-> 직렬화 가능한 객체는 인간이 읽고 이해하여 보안을 달성 할 수 있습니다.

| => 객체 설명은 물체의 상태를 가져 와서 객체 (java.lang.object)에 저장하는 과정입니다.

  • |-> 상태를 저장하기 전에 SerialversionUid 양식 입력 파일/네트워크 및 .class 파일 SerialversionUid가 동일인지 확인합니다.
    java.io.invalidclassexception을 던지지 않으면.

| => Java 객체는 클래스 또는 슈퍼 클래스가있는 경우에만 직렬화 가능합니다.

  • java.io.serializable 인터페이스 또는 중 하나를 구현합니다
  • 하위 인터페이스, java.io.externalizable.

| => 클래스의 정적 필드는 직렬화 될 수 없습니다.

class NamCls implements Serializable
{
    int NumVar;
    static String NamVar = "I won't be serializable";;
}

| => 클래스의 변수를 시리얼링하고 싶지 않은 경우 과도 키워드 사용

class NamCls implements Serializable
{
    int NumVar;
    transient String NamVar;
}

| => 클래스가 직렬화 할 수있는 경우 모든 하위 클래스도 직렬화 할 수 있습니다.

| => 클래스에 다른 클래스의 참조가있는 경우 모든 참조는 직렬화 할 수 있어야합니다. 그렇지 않으면 직렬화 프로세스가 수행되지 않습니다. 그러한 경우,
NotserializableException은 런타임에 발생합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top