자바 - 직렬화
안녕하세요, 미래의 자바 마법사 여러분! 오늘은 자바 직렬화의 흥미로운 세계로 여행을 떠날 거예요. 프로그래밍에 새로운 사람이라도 걱정 마세요 – 여러분의 친절한 가이드가 저가 될 테니까요. 저희는 걸음마다 이해를 돕으러 갈 거예요. 이 튜토리얼을 끝내면 프로처럼 객체를 직렬화할 수 있게 될 거예요!
직렬화란 무엇인가요?
코드에 뛰어들기 전에 직렬화가 무엇인지 이해해 보겠습니다. 마치 여러분이 맛있는 샌드위치(자바에서는 객체)를 친구에게 우편으로 보내고 싶은 것처럼 상상해 보세요. 그 샌드위치를 그대로信封에 넣을 수는 없죠, right? 대신, 그것을 재료로 나누어 쓰고, 그것들을一张紙에 적어서 보내야 합니다. 친구가 그것을 받으면 지시에 따라 샌드위치를 다시 만들 수 있습니다. 이러한 객체를 쉽게 저장하거나 전송할 수 있는 형식으로 나누는 과정을 직렬화라고 합니다. 반대의 과정인 – 직렬화된 데이터에서 객체를 다시 만드는 것은 역직렬화라고 합니다.
왜 직렬화가 필요한가요?
자바에서 직렬화는 여러 가지 이유로 매우 유용합니다:
- 객체 상태 저장: 객체의 상태를 저장하고 나중에 다시 만들 수 있습니다.
- 네트워크 통신: 네트워크를 통해 객체를 보낼 수 있습니다.
- 캐싱: 직렬화된 객체는 빠른 접근을 위해 캐시에 저장될 수 있습니다.
- 깊은 복사: 객체의 깊은 복사를 만드는 쉬운 방법을 제공합니다.
이제, 손을 씻고 코드로 뛰어들어 보겠습니다!
자바에서 직렬화가 어떻게 작동하는가
자바에서는 직렬화가 언어에 내장되어 있어 우리의 삶을 더 쉽게 만듭니다. 객체를 직렬화할 수 있게 하려면 두 가지를 해야 합니다:
-
Serializable
인터페이스를 구현합니다. - 모든 객체 필드도 직렬화 가능해야 합니다.
이제 간단한 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 + "}";
}
}
이 예제에서, Person
은 Serializable
을 구현합니다. 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();
}
}
}
이것이 무엇을 하는지 분석해 보겠습니다:
-
Person
객체를 생성합니다. -
FileOutputStream
를 사용하여 "person.ser" 파일에 씁니다. -
FileOutputStream
를ObjectOutputStream
으로 감싸서 직렬화를 합니다. -
writeObject()
를 호출하여Person
객체를 직렬화합니다. - 스트림이 올바르게 닫히도록 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();
}
}
}
이以下是 일어나고 있는 일:
-
FileInputStream
를 사용하여 "person.ser"에서 읽습니다. - 그것을 역직렬화를 위해
ObjectInputStream
으로 감싸습니다. -
readObject()
를 호출하여 객체를 역직렬화하고Person
으로 캐스팅합니다. - 역직렬화된 객체를 출력합니다.
이것을 실행하면 원래의 Person
객체가 출력될 것입니다!
자바에서 직렬화에 대한 중요한 점
-
SerialVersionUID: 직렬화의 버전 관리를 위해 클래스에
serialVersionUID
를 정의할 수 있습니다:
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
// ... 나머지 클래스
}
-
Transient 필드: 직렬화되지 않도록 하고 싶은 필드(예: 민감한 데이터)는
transient
로 표시합니다:
public class Person implements Serializable {
private String name;
private int age;
private transient String password; // 직렬화되지 않음
// ... 나머지 클래스
}
-
직렬화 과정的自定义: 클래스에
writeObject()
과readObject()
메서드를 구현하여 직렬화 과정을 자유롭게 설정할 수 있습니다.
객체를 직렬화하고 역직렬화하는 데 사용되는 메서드
다음은 직렬화와 역직렬화에 사용되는 주요 메서드의 표입니다:
메서드 | 설명 |
---|---|
ObjectOutputStream.writeObject(Object obj) |
객체를 직렬화합니다 |
ObjectInputStream.readObject() |
객체를 역직렬화합니다 |
Externalizable.writeExternal(ObjectOutput out) |
사용자 정의 직렬화 메서드 |
Externalizable.readExternal(ObjectInput in) |
사용자 정의 역직렬화 메서드 |
결론
축하합니다! 여러분은 자바 직렬화의 세계로 첫 걸음을 내딛었습니다. 우리는 직렬화가 무엇인지, 왜 유용한지, 자바에서 어떻게 구현할 수 있는지 다루었습니다. 기억해 두세요, 연습이 실력을 만든다고 해서 다양한 객체와 시나리오에 대해 실험해 보세요.
자바의 여행을 계속할수록 직렬화는 다양한 문맥에서 등장합니다 – 게임 상태를 저장하고 네트워크를 통해 데이터를 전송하는 것에서부터. 이는 여러분의 프로그래밍 도구箱에 매우 강력한 도구입니다.
코드를 계속 작성하고, 계속 배우며, 가장 중요한 것은 즐기세요! 언제か 여러분이 전체 가상 세계를 직렬화할 수 있는 날이 오지 않을까요. 그때까지는 즐겁게 코딩하세요!
Credits: Image by storyset