Java Object Stream과 직렬화
1. 기본 개념
1.1 직렬화(Serialization)
- 객체를 바이트 형식으로 변환하는 과정
- 파일 저장이나 네트워크 전송을 위해 사용
- ObjectOutputStream을 통해 구현
1.2 역직렬화(Deserialization)
- 바이트 스트림을 객체로 복원하는 과정
- 저장된 데이터나 수신된 데이터를 객체로 변환
- ObjectInputStream을 통해 구현
2. ObjectOutputStream 사용
2.1 기본 사용법
public class ObjectOutputExample {
public void saveObject() {
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("object.dat"))) {
Person person = new Person("John", 30);
oos.writeObject(person);
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.2 여러 객체 직렬화
public class MultipleObjectOutput {
public void saveObjects() {
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("objects.dat"))) {
List<Person> people = Arrays.asList(
new Person("John", 30),
new Person("Jane", 25)
);
oos.writeObject(people);
}
}
}
3.1 기본 사용법
public class ObjectInputExample {
public void loadObject() {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("object.dat"))) {
Person person = (Person) ois.readObject();
System.out.println(person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
3.2 여러 객체 역직렬화
public class MultipleObjectInput {
public void loadObjects() {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("objects.dat"))) {
List<Person> people = (List<Person>) ois.readObject();
people.forEach(System.out::println);
}
}
}
4. Serializable 구현
4.1 기본 구현
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
4.2 transient 필드 사용
public class User implements Serializable {
private String username;
private transient String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
}
5. 실전 활용 예제
5.1 객체 상태 저장/복원
public class GameStateManager {
public void saveGameState(GameState state) {
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("game.save"))) {
oos.writeObject(state);
}
}
public GameState loadGameState() {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("game.save"))) {
return (GameState) ois.readObject();
}
}
}
5.2 객체 깊은 복사
public class ObjectCloner {
public static <T extends Serializable> T deepCopy(T object) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (T) ois.readObject();
} catch (Exception e) {
throw new RuntimeException("복사 실패", e);
}
}
}
6. 주의사항과 모범 사례
6.1 버전 관리
public class VersionedClass implements Serializable {
private static final long serialVersionUID = 2L;
private String newField;
}
6.2 보안 고려사항
- 민감한 데이터는 transient 선언
- 역직렬화 시 타입 안전성 검증
- 신뢰할 수 있는 소스의 데이터만 역직렬화