-
객체 직렬화(Serialization) / 역직렬화(DeSerialization)란??Java 2018. 8. 18. 17:25반응형
직렬화와 역직렬화
뭔가 단어는 심오하고 어려운 뜻을 가지고 있는 것지만
알고나면 간단하고 쉬..운...??! 용어입니다..(^^;;)
0. 직렬화와 역직렬화를 하기 위해서는!!
- 직렬화와 역직렬화를 위해서는 java.io.Serializable interface를 implements 해야 합니다.
또는 Serializable interface를 implements한 클래스를 상속 받아야 합니다.
- Serializable를 위해 아래의 함수 중 목적에 맞게 사용하면 됩니다.
( wirteObject(), readObject(), readObjectNoDate() 입니다. )
1. 직렬화 ( Serialization ) 란?
- 객체직렬화란 Heap 영역에 저장된 메모리에 객체의 정보를 외부로 전송할 수 있는 상태로 만드는 것을 말합니다.
- 여러 이유로 인해 직렬화 대상에서 제외를 필요로 할 때 transient를 이용하여 직렬화 대상에서 제외시킬 수 있습니다.
- 객체 직렬화를 위해 사용되는 스트림은 ObjectOutputStream 과 wirteObject() 입니다.
2. 역직렬화 ( DeSerialization ) 란?
- 직렬화하여 저장된 객체의 정보를 다시 Heap 영역의 메모리로 복원하는 것을 말합니다.
- 객체 역직렬화를 위해 사용되는 스트림은 ObjectInputStream 과 readObject() 입니다.
3. SerialVersionUID 란?
1) 직렬화를 하면 클래스 내부에 SerialVersionUID 라는 long타입의 static final 상수로 클래스 버전의 아이디를 명시해야 합니다.
2) ServiaVersionUID를 선언하지 않아도 모든 클래스는 UID를 가지고 있습니다.
하지만 클래스의 정의가 바뀐다면 UID도 새로운 버전을 할당 해주기 때문에 직렬화할 때의 버전 번호와 역직렬화할 때의 버전 번호가
일치하지 않는다면 java.io.InvalidClassException 이 발생하여 역직렬화를 할 수 없습니다.
3) 그렇기 때문에 개발자가 직접 UID를 명시해줌으로써
클래스의 정의가 바뀐다고 하더라도 버전 번호는 바뀌지 않고 직렬화 / 역직렬화가 가능합니다.
4. 사용 예제
0) 직렬화 / 역직렬화를 위한 Person Class를 만들어 줍니다.
① 직렬화 / 역직렬화를 위한 Serializable interface를 implements 하였습니다.
② 번호는 숨기기 위해 transient와 같이 선언하였습니다.
1234567891011121314151617181920212223242526272829303132333435363738import java.io.Serializable;public class Person ①implements Serializable{private static final long serialVersionUID = 9077429981170714833L;/*** 객체 직렬화시 부여되는 클래스 버젼의 아이디를 명시한다.*/private String name;private int age;private ②transient String number;public Person(String name, int age, String number) {super();this.name = name;this.age = age;this.number = number;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}}cs 1) 직렬화(Serialization)
① 파일 저장을 위해 FileOutputStream 클래스를 사용하여 파일을 저장할 위치를 가지고
② 직렬화를 위한 ObjectOutputStream 클래스의 인수로 사용하였습니다.
③ 직렬화를 만들어주는 wirteObject함수를 사용하여 Person 객체를 인수로 넘겨주었습니다.
123456789101112131415161718192021222324252627282930313233import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;//객체 직렬화 테스트public class TestSerialization {public static void main(String[] args) {FileOutputStream fos;try {①fos = new FileOutputStream("C:\\test\\person.obj");Person p = new Person("아잉후", 29, "01012341234");Person p2 = new Person("아잉후후", 29, "01043214321");ObjectOutputStream oos;②oos = new ObjectOutputStream(fos);③oos.writeObject(p);③oos.writeObject(p2);System.out.println("Person 객체 직렬화하여 파일에 저장");oos.close();} catch (FileNotFoundException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}cs ※ 결과 화면
- 성공적으로 출력문을 출력하고 파일로 person.obj가 만들어짐을 볼 수 있습니다.
2. 역직렬화(DeSerialization)
① 저장한 파일 입력을 위해 FileInputStream 클래스를 사용하여 파일을 저장할 위치를 가지고
② 직렬화를 위한 ObjectInputStream 클래스의 인수로 사용하였습니다.
③ 직렬화를 읽어드리는 readObject함수를 사용하였습니다.
12345678910111213141516171819202122232425262728293031323334import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.ObjectInputStream;import step7.Person;// 객체 역직렬화 테스트public class TestDeSerialization {public static void main(String[] args) {String path = "C:\\test\\person.obj";try {①FileInputStream fis = new FileInputStream(path);②ObjectInputStream ois = new ObjectInputStream(fis);③Person p = (Person)ois.readObject();③Person p2 = (Person)ois.readObject();System.out.println(p.getName() + " " + p.getAge() + " " +p.getNumber());System.out.println(p2.getName() + " " + p2.getAge() + " " +p2.getNumber());ois.close();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}cs ※ 결과 화면
- 출력문이 정상적으로 출력되었으며, transient를 이용한 number는 null로 출력되는 것을 볼 수 있습니다.
반응형'Java' 카테고리의 다른 글
자바에서 접근제어자!! (0) 2018.12.28 String vs StringBuilder vs StringBuffer 이해하기!! (0) 2018.08.30 Scanner vs BufferedReader (0) 2018.08.09 JDBC란 무엇일까? (0) 2018.08.01 Java SE 환경설정하는 방법 (0) 2018.07.29