티스토리 뷰

직렬화 (serialization)

Java의 직렬화는 객체를 파일에 저장하거나 네트워크를 통해 전송할 수 있는 바이트 스트림으로 변환하는 프로세스입니다.
직렬화된 바이트 스트림을 다시 개체로 변환하는 역과정을 역직렬화라고 합니다.

Java에서 직렬화는 클래스가 직렬화될 수 있음을 나타내는 Serializable 인터페이스와 보조 스트림를 사용하여 구현됩니다.

정확히는 Serializable 인터페이스는 클래스를 직렬화 가능으로 표시하는 데 사용되지만 실제 직렬화 프로세스는 개체를 읽고 쓸 때 추가 기능을 제공하는 보조 스트림인 ObjectOutputStream 및 ObjectInputStream 클래스를 통해 수행됩니다.

ObjectInputStream과 ObjectOutputStream

생성자 설명
ObjectInputStream(InputStream in) InputStream을 생성자의 매개변수로 받아 ObjectInputStream을 생성합니다.
ObjectOutputStream(OutputStream out) OutputStream을 생성자의 매개변수로 받아 ObjectOutputStream을 생성합니다.

직렬화의 장점 : 직렬화 왜 할까?

  1. 데이터 지속성
    • 직렬화를 통해 Java 개체를 파일 시스템이나 데이터베이스에 저장한 다음 나중에 검색할 수 있습니다.
    • 이 기능은 나중에 사용할 수 있도록 개체 또는 응용 프로그램의 상태를 저장하려는 경우에 유용합니다.
  2. 네트워크 통신
    • 직렬화를 사용하면 Java 개체를 네트워크를 통해 바이트 스트림으로 보낼 수 있습니다.
    • 이 기능은 서버가 Java 개체를 클라이언트에 보내야 하는 클라이언트-서버 응용 프로그램에 유용합니다.
  3. 개체 복제
    • 직렬화는 Java에서 개체의 복제본을 만드는 쉬운 방법을 제공합니다.
    • 개체를 직렬화한 다음 역직렬화하면 원본 개체의 복사본을 만들 수 있습니다.
  4. 보안: 직렬화를 사용하면 네트워크를 통한 안전한 전송을 위해 Java 객체를 디지털 서명하고 암호화할 수 있습니다.

Serializable 인터페이스

  • 직렬화는 인스턴스의 내용이 외부로 유출되는 것이므로 프로그래머가 해당 객체에 대한 직렬화 의도를 표시해야 함
  • 구현 코드가 없는 marker interface, JVM에 직렬화를 할 것임을 알려준다
  • transient : 직렬화 하지 않으려는 멤버 변수에 사용함 (Socket등 직렬화 할 수 없는 객체)
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()
	{
		return name + "," + job;
	}
}
public class SerializationTest {
	public static void main(String[] args) throws ClassNotFoundException {
		Person personAhn = new Person("이순신", "대표이사");
		
		try(FileOutputStream fos = new FileOutputStream("serial.out");
				ObjectOutputStream oos = new ObjectOutputStream(fos)){
			
			oos.writeObject(personAhn);
		
		}catch(IOException e) {
			e.printStackTrace();
		}
			
		try(FileInputStream fis = new FileInputStream("serial.out");
			ObjectInputStream ois = new ObjectInputStream(fis)){
			
			Person p1 = (Person)ois.readObject();			
			System.out.println(p1);
		}catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Externalizable Interface

Externalizable 인터페이스는 프로그래머에게 직렬화 프로세스를 완전히 제어할 수 있도록 합니다.

Serializable은 메서드가 없는 마커 인터페이스이지만 Externalizable에는 writeExternal() 및 readExternal() 이라는 두 메서드의 구현이 필요합니다.

  • writeExternal() 메서드는 개체를 스트림에 쓰는 방법을 지정
  • readExternal() 메서드는 스트림에서 개체를 읽는 방법을 지정합니다.

Externalizable을 사용하는 이점은 직렬화 프로세스에 대한 유연성과 제어가 더 크다는 것입니다.
프로그래머는 특정 필드만 포함하거나 직렬화된 데이터에 대한 사용자 지정 형식을 사용하도록 선택할 수 있으므로 직렬화된 개체가 더 작아지고 잠재적으로 성능이 향상됩니다

class Person implements 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);
	}

	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		name = in.readUTF();
	}
	
}

부족한 점이나 잘못 된 점을 알려주시면 시정하겠습니다 :>

728x90