직렬화(Serialization)
객체의 직렬화
- 객체를 스트림 형식으로 파일에 저장하는 방법
- 객체를 직렬화 하기 위해서는 해당 객체에 Serializable 인터페이스를 구현해주어야 한다.
Serializable 인터페이스
- 구현한 해당 클래스의 모든 멤버변수가 직렬화 대상이 됨
- 객체를 스트림을 통해 입출력 하기 위해서는 직렬화 과정이 필요하다
- 멤버변수 중 직렬화 대상에서 제외하고 싶다면 transient 키워드를 사용하여 제외시킨다
- transient: 직렬화 되지 않을 멤버변수에 지정
- 직렬화가 되지 않는 멤버변수는 기본값으로 저장된다
- 직렬화 - ObjectOutputStream
- 역직렬화 - ObjectInputStream
회원정보를 객체로 출력하는 예제
- T15_ObjectStreamTest.java
1단계: 회원정보 담을 VO class
class Member implements Serializable {
}
private transient String name;
private int age;
private String addr;
}
2단계: main에서 직렬화/역직렬화 실행
Member mem1 = new Member("홍길동", 20, "대전");
Member mem2 = new Member("일지매", 30, "경기");
Member mem3 = new Member("이몽룡", 40, "강원");
Member mem4 = new Member("성춘향", 20, "제주");
try {
ObjectOutputStream oos =
new ObjectOutputStream
(new BufferedOutputStream(
(new FileOutputStream("d:/D_Other/memObj.bin")));
oos.writeObject(mem1);
oos.writeObject(mem2);
oos.writeObject(mem3);
oos.writeObject(mem4);
System.out.println("쓰기 작업 완료");
oos.close();
ObjectInputStream ois =
new ObjectInputStream
(new BufferedInputStream
(new FileInputStream("d:/D_Other/memObj.bin")));
Object obj = null;
try {
while ((obj = ois.readObject()) != null) {
Member mem = (Member) obj;
System.out.println("이름 : " + mem.getName());
System.out.println("나이 : " + mem.getAge());
System.out.println("주소 : " + mem.getAddr());
System.out.println("----------------------");
}
ois.close();
} catch (ClassNotFoundException e) {
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("출력 작업 끝...");
}
- 결과
- e.printStackTrace() 주석처리함
Serializable 구현 못하는 상황에서 수동으로 직렬화 처리하는 방법
- T16_NonSerializableParentTest.java
- 이해 하면 다행이고 몰라도 어쩔 수 없음~!!
부모클래스가 Serializable 인터페이스를 구현하고 있지 않을 경우, 부모 객체의 필드값 처리 방법
- 1) 부모 클래스가 Serializable 인터페이스를 구현하도록 해야한다.
- 이게 불가능한 경우에는 2번 써야함
- jdk나 library, framework 개발하는 사람들은 1번방법 못씀
- Parent 하나 구현시키면 Parent 자식들도 다 구현해야하기때문에 조심스럽게 씀
- 2) 자식클래스에 writeObject()와 readObject() 메서드를 이용하여 부모객체의 필드값을 처리할 수 있도록 직접 구현한다.
1단계: 부모 클래스 정의
class Parent {
private String parentName;
public String getParentName() {
return parentName;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
}
2단계: 자식 클래스 정의
class Child extends Parent implements Serializable {
private String childName;
public String getChildName() {
return childName;
}
public void setChildName(String childName) {
this.childName = childName;
}
private void writeObject(ObjectOutputStream out) throws IOException{
out.writeUTF(getParentName());
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
setParentName(in.readUTF());
in.defaultReadObject();
}
}
3단계: main에서 실행
FileOutputStream fos =
new FileOutputStream("d:/D_Other/nonSerializableTest.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Child child = new Child();
child.setParentName("붐호");
child.setChildName("자슥");
oos.writeObject(child);
oos.flush();
oos.close();
FileInputStream fis = new FileInputStream("d:/D_Other/nonSerializableTest.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
Child child2 = (Child) ois.readObject();
System.out.println("parentName : " + child2.getParentName());
System.out.println("childName : " + child2.getChildName());
ois.close();
oos.close();