컴퓨터공학 💻 도서관📚
Part2. 6-17 직렬화 (serialization) 본문
serialization 이란?
- 인스턴스의 상태를 그대로 파일 저장하거나 네트웍으로 전송하고 (serialization) 이를 다시 복원(deserialization) 하는 방식
- 자바에서는 보조 스트림을 활용하여 직렬화를 제공함
- ObjectInputStream과 ObjectOutputStream
(input스트림, output스트림에서 하는 일은 데이터 형에 따른 메서드를 호출해서 저장하고 복원하는 것인데
직렬화에서 하는 일은 object 자체, 인스턴스 자체를 저장하고 그다음에 이를 다시 복원하는 것이다.
이거를 파일에서 쓰거나 네트워크로 전송할 때 많이 한다
객체가 인스턴스화돼서 메모리에 있으면 생성자로 생성한 값이 아니라 그 이후에 메서드들이 호출하면서 계속 값이 변화하는데
어느 순간 그 상태 그대로를 저장을 한다거나 아니면 네트워크에 전송을 할 일이 있을 때
바이트 스트림의 연속으로 만들어서 이 객체의 정보를 그대로 저장했다가 이 정보를 그대로 복원할 수 있게끔 사용하는 것이다.
그때 사용하는 스트림이 보조 스트림인 ObjectInputStream , ObjectOutStream 이다.)
Serializable 인터페이스
- 직렬화는 인스턴스의 내용이 외부로 유출되는 것이므로 프로그래머가 해당 객체에 대한 직렬화 의도를 표시해야 함
(직렬화는 인스턴스 내용이 serializable 하다라고 명시를 해줘야 한다
이렇게 명시를 하기 위해서 serializable 인터페이스를 구현한다 해줘야 한다.
그리고 이건 구현 코드는 없고 이 객체가 직렬화 가능하다라는 것을 알려주는 인터페이스이고
이런 인터페이스를 마크 인터페이스라고 한다.) - 구현 코드가 없는 marker interface
- transient : 직렬화 하지 않으려는 멤버 변수에 사용함 (Socket 등은 직렬화 할 수 없는 객체)
(이 클래스에서 직렬화할 수 없는 멤버를 갖고 있는데 이 클래스는 직렬화해야 된다라고 하면 그 멤버에 transient라고 써주면 된다. 그렇게 쓰면 그 멤버는 무시하고 직렬화를 한다. ex) transient String job;
transient 한 멤버는 복원할 때 default 값을 넣어주고 객체의 default 값은 null 이다.)
class Person implements Serializable{ // 직렬화 의도 표시
private static final long serialVersionUID = -1503252402544036183L;
String name;
String job;
public Person() {}
public Person(String name, String job) {
this.name = name;
this.job = job;
}
public String toString() // toString()
{
return name + "," + job;
}
}
public class SerializationTest {
public static void main(String[] args) throws ClassNotFoundException {
Person personAhn = new Person("이순신", "대표이사");
Person personKim = new Person("김유신", "상무이사");
try(FileOutputStream fos = new FileOutputStream("serial.out");
ObjectOutputStream oos = new ObjectOutputStream(fos)){
// 직렬화(serialization)
oos.writeObject(personAhn); // write할 때는 writeObject 메서드를 이용한다.
oos.writeObject(personKim);
}catch(IOException e) {
e.printStackTrace();
}
try(FileInputStream fis = new FileInputStream("serial.out");
ObjectInputStream ois = new ObjectInputStream(fis)){
// 복원(deserialization) : serial.txt에 클래스의 정보가 들어가 있고 그거를 가지고 다시 복원을 한 것이다.
Person p1 = (Person)ois.readObject(); // readObject 하면 반환 값이 object이다. 그래서 여기에 우리가 원하는 Person 으로 캐스팅을 해주면 Person으로 반환된다.
Person p2 = (Person)ois.readObject();
System.out.println(p1);
System.out.println(p2);
}catch (IOException e) { // 밑에 설명 있음
e.printStackTrace();
}
}
}
readObject로 읽었을 때 Exception을 하나 처리해야 하는데, 읽을 때 보면 Class로 리턴이 되는데 이 Class가 읽을 때 없을 수 있다.
Classtype이 위에서 write를 하는데 그러면 이 안에 Class에 대한 정보, constructor에 대한 정보, 멤버변수에 대한 정보가 같이 다 들어간다.
다시 readObject 하려고 하면 이 Class에 대한 정보가 있어야 하는데 만약에 내가 readObject 하려는 Class가 없다면
읽을 때 ClassNotFoundException 이 떨어질 수 있다.
그래서 catch(ClassNotFoundException e) 나 catch(IOException e) 를 해야 한다.
Externalizable 인터페이스
- writerExternal()과 readExternal()메서드를 구현해야 함
- 프로그래머가 직접 객체를 읽고 쓰는 코드를 구현 할 수 있음
(Serializable은 특별히 우리가 writeObject 나 readObject만 부르면 transient한 멤버만 빼놓고는 다 직렬화가 됐다가 다시 복원을 한다.
그런데 그렇지 않고 직접 프로그래머가 객체를 읽고 쓰는 코드를 구현하고 싶다라고 하면
Externalizable 라는 인터페이스를 선언을 하면 되고 이렇게 선언을 하게 되면 뭐를 해야 되냐면 readExternal , writeExternal 메서드를 직접 구현해야 한다.
ObjectInputStream, ObjectOutputStream 을 이용해서 직렬화를 할 때는 readObject, writeObject 그냥 하면 되는데 그게 아니고 Externalizable을 할 때는 얘네들을 직접 구현을 해야 된다.)
class Person implements Externalizable{ // 여기서 Externalizable 선언하고 직렬화를 어떻게 할 건지 메서드 직접 구현해주면 된다.
String name;
String job;
public Person() {}
public Person(String name, String job) {
this.name = name;
this.job = job;
}
public String toString()
{
return name + "," + job;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException { // 직렬화 구현
out.writeUTF(name); // writeUTF 메서드 구현해서 직렬화 구현
//out.writeUTF(job);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = in.readUTF(); // readUTF 메서드 구현해서 복원 구현
//job = in.readUTF();
}
}
'✅🌲강의 복습 노트 > 패캠 JavaSpring 강의,코드 복습' 카테고리의 다른 글
Part2. 6-16 여러가지 보조 스트림 클래스들 (0) | 2025.08.31 |
---|---|
Part2. 6-15 문자 단위 입출력 스트림 (1) | 2025.08.29 |
Part2. 6-14 바이트 단위 입출력 스트림 (0) | 2025.08.22 |
Part2. 6-13 표준 입출력 스트림 (0) | 2025.08.22 |
Part2. 6-12 자바의 입출력을 위한 I/O 스트림 (통합 연산 도구) (0) | 2025.08.21 |
Comments