자바 - 직렬화

안녕하세요, 미래의 자바 마법사 여러분! 오늘은 자바 직렬화의 흥미로운 세계로 여행을 떠날 거예요. 프로그래밍에 새로운 사람이라도 걱정 마세요 – 여러분의 친절한 가이드가 저가 될 테니까요. 저희는 걸음마다 이해를 돕으러 갈 거예요. 이 튜토리얼을 끝내면 프로처럼 객체를 직렬화할 수 있게 될 거예요!

Java - Serialization

직렬화란 무엇인가요?

코드에 뛰어들기 전에 직렬화가 무엇인지 이해해 보겠습니다. 마치 여러분이 맛있는 샌드위치(자바에서는 객체)를 친구에게 우편으로 보내고 싶은 것처럼 상상해 보세요. 그 샌드위치를 그대로信封에 넣을 수는 없죠, right? 대신, 그것을 재료로 나누어 쓰고, 그것들을一张紙에 적어서 보내야 합니다. 친구가 그것을 받으면 지시에 따라 샌드위치를 다시 만들 수 있습니다. 이러한 객체를 쉽게 저장하거나 전송할 수 있는 형식으로 나누는 과정을 직렬화라고 합니다. 반대의 과정인 – 직렬화된 데이터에서 객체를 다시 만드는 것은 역직렬화라고 합니다.

왜 직렬화가 필요한가요?

자바에서 직렬화는 여러 가지 이유로 매우 유용합니다:

  1. 객체 상태 저장: 객체의 상태를 저장하고 나중에 다시 만들 수 있습니다.
  2. 네트워크 통신: 네트워크를 통해 객체를 보낼 수 있습니다.
  3. 캐싱: 직렬화된 객체는 빠른 접근을 위해 캐시에 저장될 수 있습니다.
  4. 깊은 복사: 객체의 깊은 복사를 만드는 쉬운 방법을 제공합니다.

이제, 손을 씻고 코드로 뛰어들어 보겠습니다!

자바에서 직렬화가 어떻게 작동하는가

자바에서는 직렬화가 언어에 내장되어 있어 우리의 삶을 더 쉽게 만듭니다. 객체를 직렬화할 수 있게 하려면 두 가지를 해야 합니다:

  1. Serializable 인터페이스를 구현합니다.
  2. 모든 객체 필드도 직렬화 가능해야 합니다.

이제 간단한 Person 클래스를 만들어 보겠습니다:

import java.io.Serializable;

public class Person implements Serializable {
private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}

이 예제에서, PersonSerializable을 구현합니다. Serializable 인터페이스에는 메서드가 없습니다 – 이것은 자바에게 이 클래스가 직렬화될 수 있다는 마커 인터페이스입니다.

객체를 직렬화하는 방법

이제 Person 클래스를 가지고 있으니, 객체를 직렬화해 보겠습니다:

import java.io.*;

public class SerializationDemo {
public static void main(String[] args) {
Person person = new Person("Alice", 30);

try (FileOutputStream fileOut = new FileOutputStream("person.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
out.writeObject(person);
System.out.println("Person 객체가 직렬화되고 person.ser에 저장됨");
} catch (IOException e) {
e.printStackTrace();
}
}
}

이것이 무엇을 하는지 분석해 보겠습니다:

  1. Person 객체를 생성합니다.
  2. FileOutputStream를 사용하여 "person.ser" 파일에 씁니다.
  3. FileOutputStreamObjectOutputStream으로 감싸서 직렬화를 합니다.
  4. writeObject()를 호출하여 Person 객체를 직렬화합니다.
  5. 스트림이 올바르게 닫히도록 try-with-resources 블록을 사용합니다.

이것을 실행하면 직렬화된 Person 객체가 들어 있는 "person.ser" 파일이 생성됩니다.

객체를 역직렬화하는 방법

이제 객체를 역직렬화해 보겠습니다:

import java.io.*;

public class DeserializationDemo {
public static void main(String[] args) {
try (FileInputStream fileIn = new FileInputStream("person.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)) {
Person person = (Person) in.readObject();
System.out.println("역직렬화된 Person 객체:");
System.out.println(person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}

이以下是 일어나고 있는 일:

  1. FileInputStream를 사용하여 "person.ser"에서 읽습니다.
  2. 그것을 역직렬화를 위해 ObjectInputStream으로 감싸습니다.
  3. readObject()를 호출하여 객체를 역직렬화하고 Person으로 캐스팅합니다.
  4. 역직렬화된 객체를 출력합니다.

이것을 실행하면 원래의 Person 객체가 출력될 것입니다!

자바에서 직렬화에 대한 중요한 점

  1. SerialVersionUID: 직렬화의 버전 관리를 위해 클래스에 serialVersionUID를 정의할 수 있습니다:
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
// ... 나머지 클래스
}
  1. Transient 필드: 직렬화되지 않도록 하고 싶은 필드(예: 민감한 데이터)는 transient로 표시합니다:
public class Person implements Serializable {
private String name;
private int age;
private transient String password; // 직렬화되지 않음
// ... 나머지 클래스
}
  1. 직렬화 과정的自定义: 클래스에 writeObject()readObject() 메서드를 구현하여 직렬화 과정을 자유롭게 설정할 수 있습니다.

객체를 직렬화하고 역직렬화하는 데 사용되는 메서드

다음은 직렬화와 역직렬화에 사용되는 주요 메서드의 표입니다:

메서드 설명
ObjectOutputStream.writeObject(Object obj) 객체를 직렬화합니다
ObjectInputStream.readObject() 객체를 역직렬화합니다
Externalizable.writeExternal(ObjectOutput out) 사용자 정의 직렬화 메서드
Externalizable.readExternal(ObjectInput in) 사용자 정의 역직렬화 메서드

결론

축하합니다! 여러분은 자바 직렬화의 세계로 첫 걸음을 내딛었습니다. 우리는 직렬화가 무엇인지, 왜 유용한지, 자바에서 어떻게 구현할 수 있는지 다루었습니다. 기억해 두세요, 연습이 실력을 만든다고 해서 다양한 객체와 시나리오에 대해 실험해 보세요.

자바의 여행을 계속할수록 직렬화는 다양한 문맥에서 등장합니다 – 게임 상태를 저장하고 네트워크를 통해 데이터를 전송하는 것에서부터. 이는 여러분의 프로그래밍 도구箱에 매우 강력한 도구입니다.

코드를 계속 작성하고, 계속 배우며, 가장 중요한 것은 즐기세요! 언제か 여러분이 전체 가상 세계를 직렬화할 수 있는 날이 오지 않을까요. 그때까지는 즐겁게 코딩하세요!

Credits: Image by storyset