Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

Super Coding Addict

Ch14. 자바 입출력(6) 본문

JAVA 문법

Ch14. 자바 입출력(6)

밍응애 2021. 2. 20. 23:37

< 직렬화 >

* 직렬화 (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