관리 메뉴

오버플로

[Java] 직렬화(Serializable) / transient / ObjectStream / serialVersionUID 본문

Java

[Java] 직렬화(Serializable) / transient / ObjectStream / serialVersionUID

NACO 2021. 9. 1. 22:40

 1. 직렬화 (Serializable) 

객체를 일정 크기로 쪼개는 것.

- 단, 모든 객체는 직렬화되지 않음 (직렬화 되어져야 하는 객체는 java.io.Serivalizable 인터페이스를 구현한 클래스만 가능)

- Serializable 인터페이스를 구현한 클래스로부터 생성된 instance는 일정 크기로 쪼개질 수 있음

 

* Serializable 인터페이스는 Constant와 abstract method가 없음

   - 목적 : 데이터형에 체크 (is a 관계에 대한 확인용)

   - interface에 상수/추상메소드가 없고 -able로 명명되어있으면 특정한 용도를 확인하기 위한 interface인 경우가 많다!

 

 2. transient 

- 직렬화를 막는 키워드로 변수의 접근지정자 종류

  > 객체가 가진 중요한 정보를 JVM안에서만 사용하도록 만들 수 있음 (JVM밖으로 못 나감)

- 문법)

public class Test implements Serializable{

           int i; // 직렬화 가능

           String str; // 직렬화 가능 (String이 serializable을 implements함)

           transient String str1; // serializable보다 transient가 우선되어 직렬화 막기 가능

           private transient int j; // 직렬화 막기 }

 

 3. ObectStream 

- JVM에 생성된 instance(객체)를 JVM 외부로 내보내거나,

  JVM외부에 존재하는 객체를 JVM내부로 읽어 들일 때 사용하는 Stream

- 기본형 데이터형은 JVM외부로 나갈 수 있으나 instance는 JVM외부로 나갈 수 없음

  > 기본형 데이터형은 크기가 정해져 있어서 쪼갤 수 있음

  > 인스턴스는 클래스가 Serializable 인터페이스를 구현해야 직렬화 가능

- ObjectInputStream, ObjectOutputStream 사용 (8bit Stream)

 

 4. serialVersionUID 

- 이 클래스 파일이 JVM 외부로 빠져나갔을 때 파일을 검증하기 위한 용도의 Constant

- 용도 1) 현재 JVM에서 빠져나간 객체임을 검증 가능

  용도 2) 시간에 대한 체크 가능 (만약 내가 1년뒤에 ID 번호를 바꾸면 읽어들일 때 오류 발생!!)

- 클래스는 직렬화되어서 JVM밖으로 나갔다가 조작될 수 있는 위험(보안상의 위험)이 있기 때문에

  JVM이 serial warinng을 띄움

  > 이를 검증하기 위해 serialVersionUID를 거는 것이다!

- @SuppressWarnings(“serial”) 어노테이션 처리를 해도 되지만 ID부여가 안전함

 

- EX)

private static final long serialVersionUID = -8401830166169521484L; // 내보냈을 때 기존 ID

private static final long serialVersionUID = -8401830166169521485L; // 바뀐 ID

 

이후 .readObject();를 시행하면 아래와 같은 [InvalidClassException]이 발생함!

 

// 콘솔창 오류 내용 :
java.io.InvalidClassException: day0818.MyData; local class incompatible: stream classdesc serialVersionUID = -8401830166169521484, local class serialVersionUID = -8401830166169521485

(ID가 바뀌어서 유효한 클래스가 아니라는 의미! -> 밖에 있는 직렬화된 클래스가 내부로 들어오지 못함)

 

 

 

코딩은 다음편에!

Comments