JAVA 서열 화 와 반 서열 화의 밑바닥 실현 원리 해석

기본 개념
1.서열 화 와 반 서열 화 는 무엇 입 니까?
(1)자바 서열 화 는 자바 대상 을 바이트 서열 로 바 꾸 는 과정 을 말 하 는데 자바 반 서열 화 는 바이트 서열 을 자바 대상 으로 회복 하 는 과정 을 말한다.
(2)**직렬 화:**대상 직렬 화의 가장 중요 한 용 도 는 대상 을 전달 하고 보존 할 때 대상 의 완전 성과 전달 성 을 확보 하 는 것 이다.직렬 화 는 대상 을 네트워크 에서 전송 하거나 로 컬 파일 에 저장 할 수 있 도록 질서 있 는 바이트 흐름 으로 변환 하 는 것 이다.직렬 화 된 바이트 흐름 은 자바 대상 의 상태 와 관련 된 설명 정 보 를 저장 합 니 다.직렬 화 메커니즘 의 핵심 역할 은 대상 상태의 보존 과 재건 이다.
(3)**반 직렬 화:**클 라 이언 트 는 파일 이나 네트워크 에서 직렬 화 된 대상 바이트 흐름 을 얻 은 후 바이트 흐름 에 저 장 된 대상 상태 와 설명 정 보 를 반 직렬 화 를 통 해 대상 을 재 구축 합 니 다.
(4)본질 적 으로 볼 때 직렬 화 는 실체 대상 상 태 를 일정한 형식 에 따라 질서 있 는 바이트 흐름 에 기록 하 는 것 이다.반 직렬 화 는 질서 있 는 바이트 흐름 에서 대상 상 태 를 재 구축 하고 대상 상 태 를 회복 하 는 것 이다.
2.왜 직렬 화 와 반 직렬 화가 필요 합 니까?
우 리 는 두 프로 세 스 가 원 격 통신 을 할 때 텍스트,이미지,오디 오,동 영상 등 다양한 유형의 데 이 터 를 서로 보 낼 수 있 고 이 데 이 터 는 모두 바 이 너 리 시퀀스 로 네트워크 에서 전송 된다 는 것 을 알 고 있다.
그렇다면 두 자바 프로 세 스 가 통신 을 할 때 프로 세 스 간 대상 전송 을 실현 할 수 있 을 까?정 답 은 돼!어떻게 할 까요?자바 직렬 화 와 반 직렬 화가 필요 합 니 다!
다시 말 하면 한편,발송 자 는 이 자바 대상 을 바이트 시퀀스 로 바 꾼 다음 에 네트워크 에서 전송 해 야 한다.다른 한편,수신 자 는 바이트 시퀀스 에서 자바 대상 을 복원 해 야 한다.
우 리 는 왜 자바 의 직렬 화 와 반 직렬 화 를 필요 로 하 는 지 명확 하 게 밝 힌 후에 우 리 는 자 연 스 럽 게 자바 의 직렬 화 장점 을 생각 할 것 이다.그 장점 중 하 나 는 데이터 의 지속 화 를 실현 하고 직렬 화 를 통 해 데 이 터 를 하 드 디스크 에 영구적 으로 저장 할 수 있다 는 것 이다(보통 파일 에 저장 된다).다른 하 나 는 직렬 화 를 이용 하여 원 격 통신,즉 네트워크 에서 전송 대상 의 바이트 서열 을 실현 하 는 것 이다.
전체적으로 말 하면 다음 과 같은 몇 가지 로 요약 할 수 있다.
(1)대상 을 영구적 으로 저장 하고 대상 의 바이트 순 서 를 로 컬 파일 이나 데이터 베이스 에 저장 합 니 다.
(2)직렬 화 를 통 해 바이트 흐름 의 형식 으로 대상 을 네트워크 에서 전달 하고 수신 한다.
(3)프로 세 스 간 에 대상 을 직렬 화 합 니 다.
3.서열 화 알고리즘 은 보통 절차 에 따라 다음 과 같은 일 을 한다.
(1)대상 인 스 턴 스 와 관련 된 메타 데 이 터 를 출력 합 니 다.
(2)초 류 가 없 을 때 까지 재 귀적 으로 출력 류 의 초 류 설명.
(3)클래스 메타 데이터 가 끝 난 후에 최상 위 클래스 에서 대상 인 스 턴 스 의 실제 데이터 값 을 출력 하기 시작 합 니 다.
(4)위 에서 아래로 출력 인 스 턴 스 의 데이터
2.자바 는 어떻게 직렬 화 와 반 직렬 화 를 실현 합 니까?
1.JDK 라 이브 러 리 의 직렬 화 와 반 직렬 화 API
(1)java.io.ObjectOutputStream:대상 의 출력 흐름 을 나타 낸다.
이 writeObject(Object obj)방법 은 매개 변수 가 지정 한 obj 대상 을 직렬 화하 여 얻 은 바이트 순 서 를 대상 출력 흐름 에 기록 할 수 있 습 니 다.
(2)java.io.ObjectInputStream:대상 의 입력 흐름 을 표시 합 니 다.
그것 의 readObject()방 법 원 입력 흐름 에서 바이트 시퀀스 를 읽 고 이 를 반 서열 화하 여 대상 으로 되 돌려 줍 니 다.
2.직렬 화 요구 실현
Serializable 이나 Externalizable 인 터 페 이 스 를 실현 한 클래스 의 대상 만 서열 화 될 수 있 습 니 다.그렇지 않 으 면 이상 을 던 집 니 다!
3.자바 대상 의 직렬 화 와 반 직렬 화 를 실현 하 는 방법
하나의 User 류 를 가정 하면 대상 은 직렬 화 되 어야 하 며 다음 과 같은 세 가지 방법 이 있 을 수 있다.
(1)만약 에 User 류 가 Serializable 인터페이스 만 실현 하면 다음 과 같은 방식 으로 서열 화 와 반 서열 화 를 할 수 있다.
  • Object OutputStream 은 기본 직렬 화 방식 으로 User 대상 의 비 transient 인 스 턴 스 변 수 를 직렬 화 합 니 다.
  • Objcet InputStream 은 기본 적 인 반 직렬 화 방식 으로 User 대상 의 비 transient 인 스 턴 스 변 수 를 반 직렬 화 합 니 다.
  • (2)User 클래스 가 Serializable 인터페이스 만 실현 하고 readObject(Object InputStream in)와 writeObject(Object OutputSteam out)를 정의 하면 다음 과 같은 방식 으로 직렬 화 와 반 직렬 화 를 한다.
  • Object OutputStream 에서 User 대상 의 writeObject(Object OutputStream out)를 호출 하 는 방법 을 직렬 화 합 니 다.
  • Object InputStream 은 User 대상 의 readObject(Object InputStream in)방법 을 호출 하여 역 직렬 화 합 니 다.
  • (3)User 클래스 가 Externalnalizable 인 터 페 이 스 를 실현 하고 User 클래스 가 readExternal(Object Input in)과 writeExternal(Object Output out)방법 을 실현 해 야 한다 면 다음 과 같은 방식 으로 직렬 화 와 반 직렬 화 를 해 야 한다.
  • ObjectOutputStream 에서 User 대상 의 writeExternal(ObjectOutputout)을 호출 하 는 방법 을 직렬 화 합 니 다.
  • Object InputStream 은 User 대상 의 readExternal(Object Input in)방법 을 호출 하여 역 직렬 화 합 니 다.
  • 4.JDK 라 이브 러 리 의 직렬 화 절차
    단계 1:대상 출력 흐름 을 만 듭 니 다.파일 출력 흐름 과 같은 다른 유형의 대상 출력 흐름 을 포장 할 수 있 습 니 다.
    
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\object.out"));
    STEP 2:대상 출력 흐름 의 writeObject()방법 으로 대상 쓰기:
    
    oos.writeObject(new User("xuliugen", "123456", "male"));
    5.JDK 라 이브 러 리 의 반 직렬 화 절차
    단계 1:대상 입력 흐름 을 만 듭 니 다.파일 입력 흐름 과 같은 다른 유형의 입력 흐름 을 포장 할 수 있 습 니 다.
    
    ObjectInputStream ois= new ObjectInputStream(new FileInputStream("object.out"));
    단계 2:대상 출력 흐름 의 readObject()방법 으로 대상 읽 기:
    
    User user = (User) ois.readObject();
    설명:데 이 터 를 정확하게 읽 고 역 직렬 화 를 완성 하기 위해 서 는 대상 에 게 스 트림 대상 을 출력 하 는 순서 가 대상 의 입력 흐름 에서 읽 는 대상 의 순서 와 일치 하도록 해 야 합 니 다.
    6.직렬 화 와 반 직렬 화 된 예제
    자바 의 직렬 화 와 반 직렬 화 를 잘 이해 하기 위해 간단 한 예 를 들 면 다음 과 같다.
    
    public class SerialDemo {
    
      public static void main(String[] args) throws IOException, ClassNotFoundException {
        //   
        FileOutputStream fos = new FileOutputStream("object.out");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        User user1 = new User("xuliugen", "123456", "male");
        oos.writeObject(user1);
        oos.flush();
        oos.close();
        //    
        FileInputStream fis = new FileInputStream("object.out");
        ObjectInputStream ois = new ObjectInputStream(fis);
        User user2 = (User) ois.readObject();
        System.out.println(user2.getUserName()+ " " + 
          user2.getPassword() + " " + user2.getSex());
        //          :xuliugen 123456 male
      }
    }
    
    public class User implements Serializable {
      private String userName;
      private String password;
      private String sex;
      //      、get set    
    }
    object.out 파일 은 다음 과 같 습 니 다(UltraEdit 로 열기).

    주:위의 그림 에서 0000000 h-000000c0h 는 줄 번 호 를 표시 합 니 다.0-f 표시 열;줄 뒤의 문 자 는 이 줄 의 16 진법 에 대한 설명 을 나타 낸다.상기 바이트 코드 가 서술 한 내용 에 관심 이 있 는 것 은 관련 자 료 를 대조 하여 모든 문자 가 대표 하 는 의 미 를 찾 아 볼 수 있 습 니 다.여 기 는 연구 하지 않 습 니 다!
    우리 자바 코드 를 컴 파일 한 후의'class 파일'과 유사 하 며,모든 문 자 는 일정한 의 미 를 대표 합 니 다.직렬 화 와 반 직렬 화 과정 은 바로 상기 문 자 를 생 성하 고 해석 하 는 과정 입 니 다!
    직렬 화 그림:

    역 직렬 화 그림:

    3.관련 주의사항
    1.서열 화 할 때 대상 의 상태 만 보존 하고 대상 의 방법 을 상관 하지 않 는 다.
    2.부모 클래스 가 직렬 화 를 실현 할 때 하위 클래스 는 자동 으로 직렬 화 를 실현 하고 직렬 화 된 인터페이스 가 필요 하지 않 습 니 다.
    3.한 대상 의 인 스 턴 스 변 수 는 다른 대상 을 참조 하고 이 대상 을 직렬 화 할 때 도 인용 대상 을 직렬 화 합 니 다.
    4.모든 대상 이 서열 화 될 수 있 는 것 이 아니 라 왜 안 되 는 지 에 대해 여러 가지 이유 가 있다.예 를 들 어:
    안전 상의 원인,예 를 들 어 한 대상 이 private,Public 등 field 를 가지 고 전송 할 대상,예 를 들 어 파일 을 쓰 거나 RMI 전송 을 하 는 등 직렬 화 되 어 전송 하 는 과정 에서 이 대상 의 private 등 도 메 인 은 보호 되 지 않 습 니 다.
    자원 배분 의 원인,예 를 들 어 socket,thread 류 는 직렬 화 되 거나 전송 하거나 저장 할 수 있 으 면 그들 에 게 새로운 자원 배분 을 할 수 없고 이렇게 실현 할 필요 가 없다.
    5.static 과 transient 형식의 구성원 데 이 터 를 직렬 화 할 수 없습니다.static 대표 클래스 의 상태 때문에 transient 대표 대상 의 임시 데이터 입 니 다.
    6.직렬 화 실행 시 serial VersionUID 라 는 버 전 번 호 를 사용 하여 모든 직렬 화 클래스 와 연 결 됩 니 다.이 시리 얼 번 호 는 반 직렬 화 과정 에서 직렬 화 대상 의 발송 자 와 수신 자가 이 대상 에 직렬 화 와 호 환 되 는 클래스 를 불 러 왔 는 지 검증 하 는 데 사 용 됩 니 다.그것 에 명확 한 가 치 를 부여 하 다.serial Versionuid 를 명시 적 으로 정의 하 는 데 두 가지 용도 가 있 습 니 다.
    어떤 경우 에는 클래스 의 서로 다른 버 전이 직렬 화 호 환 되 기 를 원 하기 때문에 클래스 의 서로 다른 버 전이 같은 serial VersionUID 를 가지 고 있 는 지 확인 해 야 합 니 다.
    어떤 경우 에는 클래스 의 서로 다른 버 전이 직렬 화 호 환 되 는 것 을 원 하지 않 기 때문에 클래스 의 서로 다른 버 전이 서로 다른 serial VersionUID 를 가지 고 있 는 지 확인 해 야 합 니 다.
    7.자바 는 많은 기초 류 가 serializable 인 터 페 이 스 를 실현 했다.예 를 들 어 String,Vector 등 이다.그러나 serializable 인 터 페 이 스 를 실현 하지 못 한 경우 도 있다.
    8.한 대상 의 구성원 변수 가 하나의 대상 이 라면 이 대상 의 데이터 구성원 도 저 장 됩 니 다!이것 은 깊 은 복사 본 을 직렬 화 하여 해결 할 수 있 는 중요 한 원인 이다.
    4.반 직렬 화 구멍
    관련 반 서열 화 구멍 은 관련 자 료 를 찾 아 볼 수 있 으 니 여 기 는 소개 하지 않 겠 습 니 다.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기