2021-07-23 강의록_객체 직렬화, 역직렬화

MIN.DI·2021년 7월 23일
0

강의록

목록 보기
40/54

객체의 직렬화(Serialization) & 역직렬화(De-serialization)

1. 전제

힙에 있는 객체-->파일로 저장
메모리에 생성되어있는 객체 --> 데이터로 변환

이 객체를 생성한 클래스의 전제사항
객체를 생성한 클래스는, 반드시 Serializable 인터페이스를 implements 해야한다!
(내부에 멤버, 메소드가 하나도 없는 Tag Interface (JVM이 특별하게 취급함)

2. 객체의 직렬화 (Serialization)

-힙 영역의 객체를 바이트 열로 바꾸는 것(변환)
-객체를 파일/네트워크로 출력할 때 반드시 발생.

3. 객체의 역직렬화(De-serialization)

-바이트열을 힙 객체로 바꾸는 것(변환)
-파일/네트워크로부터, 바이트열을 힙의 객체로 변환할 때 수행

4. 객체의 직렬화/역직렬화 대상

-객체의 메소드는 무조건 (역)직렬화에서 제외
(메소드라는 건 코드 덩어리에 불과. 데이터를 가지고있지 않다.
데이터를 가지고 있는 것은 필드임.
파일에도 메소드는 저장되지 않는다!!)
-객체의 필드가 대상(데이터를 저장하고 있기 때문)
단, transient 한정자 붙은 필드는 객체의 직렬화에서 제외
static키워드가 붙은 필드도 직렬화에서 제외

5. 직렬화/역직렬화 대상이 될 수 없는 필드를 가지고 있는 객체가 있을 때

이 객체의 클래스에 아래와 같은 메소드를 선언하면, 우리가 직접 객체의 직렬화/ 역직렬화를 대신 수행할 수 있다.
-객체의 직렬화 직접 수행하는 메소드:

private void writeObject(ObjectOutputStream out) throws IOException{}

-객체의 역직렬화 직접 수행하는 메소드:

private void readObject(ObjectInputStream in) 
		 throws IOException, ClassNotFoundException

어찌어찌한 사정으로, Serializable 인터페이스를 implements 할 수 없는 상황일 때, 우리가 직접 수행할 수 있다!


SerialVersionUID

UUID ==> Universal Unique Identifier.
private static final long serialVersionUID = -5488663228028532826L;

컴파일된 클래스의 버전을 명시한 것. Serializable 클래스를 컴파일하면, 그 안에는 반드시 이 클래스의 버전을 명시해줘야 함.
그 버전이 바로 serialVersionUID임.
이것이 객체의 직렬화 역직렬화와 관련이 있다.

Serializable 한 클래스 A가 있다.

객체 혼자만 있고 클래스가 없을수는 없다.
서울에서 토론토로 A클래스를 보내려고 하는데,(WAS를 통해)

서울과 토론토 serialVersionUID의 값=클래스의 버전이
객체 직렬화, 역직렬화 할때 값이 똑같아야 함.

객체를 서로 주고받을때, 이 객체를 표현하고 있는 클래스의 버전이 같냐? 다르냐? 증명해주는 것이 serialVersionUID임.
객체의 직렬화 역직렬화 과정에서, 양쪽의 클래스 버전은 서로 같아야 함.
같지 않으면 오류이다.

UUID를 만들지 않았을 때, 기존 클래스 소스를 변경하면 재 컴파일이 이루어지면서
자바 컴파일러가 UUID를 자동으로 변경한다. (새롭게 부여함)

UUID는 현재 컴파일된 버전!!!
직렬화로 저장할 때의 클래스 버전과, 역직렬화로 복원할 클래스의 버전이 맞지 않다!

java.io.InvalidClassException 예외 발생
stack trace 보면 serialVersionUID가 다르다는 메시지 출력됨.

따라서 UUID를 직접 지정(고정)해 놓아야 함.
기존에 직렬화 할 때의 필드만 건드리지 않으면, 이후 다른 소스가 추가되어도 문제가 없다.

profile
내가 보려고 쓰는 블로그

0개의 댓글