Super Coding Addict
Ch14. 자바 입출력(6) 본문
< 직렬화 >
* 직렬화 (Serialization)
- 인스턴스의 상태를 그대로 저장하거나 네트웍으로 전송하고 이를 다시 복원(Deserialiation)하는 방식
- ObjectInputStream과 ObjectOutputSream사용 (보조스트림)
--> 앞에서 DataInputStream과 DataOutputStream에는 Object를 읽고 쓰는 기능이 없었으나, 이 Object~Stream에서 제공된다
* Serializable 인터페이스
- 직렬화는 인스턴스의 내용이 외부(파일이나 네트웍)로 유출되는 것이므로 프로그래머가 객체의 직렬화 가능 여부 명시
- 구현 코드가 없는 mark interface --> Serializable이라는 인터페이스를 선언해줌으로써 이 객체가 직렬화 가능하다고 명시
- 예제
# SerializationTest 클래스
package Ch14.stream.serialization;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
class Person{
String name;
String job;
public Person(String name, String job) {
this.name = name;
this.job = job;
}
public String toString() {
return name + ", " + job;
}
}
public class SerializationTest {
public static void main(String[] args) {
Person personLee = new Person("이순신", "엔지니어");
Person personKim = new Person("김유신", "선생님");
try(FileOutputStream fos = new FileOutputStream("serial.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos)){
oos.writeObject(personLee);
oos.writeObject(personKim);
}catch(IOException e) {
System.out.println(e);
}
}
}
--> FileOutputStream으로 이 객체에 대해 내용을 저장한다고 할 때 이 객체에 대한 여러 정보들도 같이 저장을 해야하는데, 단순히 파일에 문자로 기록을 한다고 할 수 없기에 ObjectOutputStream이라는 보조스트림으로 감싸준다
--> 실행을 하면, NotSerializableException이 떨어지는데 직렬화 가능여부를 명시하지 않았기 때문!
--> 이렇게 Serializable 인터페이스를 선언해줘야 함
package Ch14.stream.serialization;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Person implements Serializable{
String name;
String job;
public Person(String name, String job) {
this.name = name;
this.job = job;
}
public String toString() {
return name + ", " + job;
}
}
public class SerializationTest {
public static void main(String[] args) {
Person personLee = new Person("이순신", "엔지니어");
Person personKim = new Person("김유신", "선생님");
try(FileOutputStream fos = new FileOutputStream("serial.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos)){
oos.writeObject(personLee);
oos.writeObject(personKim);
}catch(IOException e) {
System.out.println(e);
}
try(FileInputStream fis = new FileInputStream("serial.dat");
ObjectInputStream ois = new ObjectInputStream(fis)){
Person p1 = (Person)ois.readObject();
Person p2 = (Person)ois.readObject();
System.out.println(p1);
System.out.println(p2);
}catch(IOException e) {
System.out.println(e);
}catch(ClassNotFoundException e) {
System.out.println(e);
}
}
}
--> serial.dat파일에 직렬화를 한 후, 다시 읽어온다
--> ObjectInputStream으로 읽어오면 반환값이 Object이므로 형변환을 해주는데 다운캐스팅보다는 InstanceOf를 써주는게 좀더 안전하다
--> 결과를 보면 복원이 잘 되었음을 알 수 있다
--> 직렬화하고자 하는 Person 클래스에서 transient 키워드를 사용해 특정 변수 직렬화하지 않을 수 있다
( 가령 socket 등은 직렬화할 수 없으므로 transient 키워드 사용)
--> 여기선 job이라는 변수를 직렬화하지 않겠다는 의미로 결과값은 이렇게 나오게 된다
--> cf. Externalizable 인터페이스 구현
--> Serializable 인터페이스 대신 Externalizable 인터페이스를 구현하면, 이는 마크 인터페이스가 아니기에 writeExternal메서드와 readExternal 메서드를 오버라이딩하게 된다
'JAVA 문법' 카테고리의 다른 글
Ch14. 자바 입출력(8) - 직접 코딩해보기 (0) | 2021.02.21 |
---|---|
Ch14. 자바 입출력(7) (0) | 2021.02.21 |
Ch14. 자바 입출력 (5) (0) | 2021.02.18 |
Ch14. 자바 입출력 (4) (0) | 2021.02.18 |
Ch14. 자바 입출력 (3) (0) | 2021.02.18 |