티스토리 뷰

프로그래밍/JAVA

JAVA 역직렬화 : 객체 복구

rlawlstjd007 2016. 10. 26. 17:44

 어떤 객체를 직렬화하는 것과 관련된 가장 중요한 점은 나중에 JVM을 다시 실행시킬 때, 또는 아예 다른 JVM에서

실행시킬 때에도 원래의 상태로 되돌릴 수 있어야 한다는 점인데, 역질렬화는 직렬화를 뒤집어놓은 것과 비슷합니다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FileInputStream fileStream = new FileInputStream("MyGame.ser");
//FileInputStream 을 만든다.
 
ObjectInputStream os = new ObjectInputStream(fileStream);
//ObjectInputStream 을 만든다.
 
Object one = os.readObject();
Object two = os.readObject();
Object three = os.readObject();
//객체를 읽는다, readObject()를 호출하면 그 스트림의 다음 객체를 받아올 수 있다. 
 
GameCharacter elf = (GameCharacter) one;
GameCharacter troll = (GameCharacter) two;
GameCharacter magician= (GameCharacter) three;
//객체를 캐스트 한다 readObject()의 리턴값은 object이다. 그렇기 때문에 원래 유형으로 다시 캐스트 한다.
 
os.close
 
cs

 
 객체를 역질렬화할 때 JVM은 직렬화 되었던 객체가 직렬화 당시에 가지고 있던 것과 똑같은 상태를 가지는 객체를
힙 안에 새로 만들려는 시도를 합니다. NULL 또는 기본 원시값을 가지게 되는 transient로 지정된 변수를 제외하고 말이죠.



 과정은 다음과 같습니다.

1. 스트림으로 부터 객체를 읽어옵니다.

2. JVM에서 (직렬화된 객체와 함께 저장된 정보를 통해) 객체의 클래스 유형을 결정합니다.

3. JVM에서 객체의 클래스를 찾아서 불러오려는 시도를 합니다. 클래스를 탖거나 불러오는 데 실패하면 JVM에서는 예외를 
던지고 역질렬화는 실패 합니다.

4. 새로운 객체는 객체의 힙에 공간을 할당받지만 직렬화된 객체의 생성자는 실행되지 않습니다. 생성자가 실행된다면 
객체의 상태가 원래 '새로운' 객체의 상태로 돌아갈텐데, 그러면 안됩니다. 힙에 만들어지는 객체는 처음 생성될 때의
상태로 되돌아가야 하기 때문이다.

5. 객체의 상속 트리에서 그 위 어딘가에 직렬화 할 수 없는 클래스가 있다면 그 직렬화 할 수 없는 클래스가 있다면 직렬화
 할 수 없는 클래스의 생성자가 실행됩니다. (그 클래스의 상위클래스를 직렬화할 수 있는 경우에도 마찬가지 입니다) 
 일단 생성자 연쇄 호출이 시작되고 나면 멈출 수가 없기 때문에 가장 가까운 직렬화할 수 없는 클래스부터 시작 해서
 그 위로 있는 모든 상위클래스의 생성자에서 상태를 새로 초기화하게 됩니다.

6. 객체의 인스턴스 변수에 직렬화된 상태값이 대입됩니다. transient로 지정된 변수는 객체 레퍼런스인 경우에은 
 null이, 원시 변수인 경우에는 기본값(0, false 등)이 주어집니다.



반응형
댓글