Java - Serialization
Java - Serialization
- Serialization은 Object를 json, xml과 같은 binary data format으로 변환하는 것을 말하고, 반대로 json, xml로부터 Object로 변경하는 것을 Deserialization이라고 합니다.
Student.java
Studentclass를 다음과 같이 정의해줍니다.- 내부에 static method로
serialize,deserialize를 각각 만들었습니다. ObjectOutputStream,ObjectInputStream을 사용하여 Object를 쓰고 읽습니다. 저는 이렇게 만들어진 stream을 File로 쓰도록 만들었습니다.- 변수에
trasient를 선언하는 경우, serialization시에 해당 값이 null로 표시됩니다. 보안상 민감한 field의 경우transient를 사용하여 포함되지 않도록 할 수 있죠.
import java.io.*;
public class Student implements Serializable {
// serialVersionUID는 무엇인가.
private static final long serialVersionUID = 1L;
private String name;
// transient: Serialization시에 제외하고 싶을 경우 사용합니다.
private transient double gpa;
// Constructor
public Student(String name, double gpa) {
this.name = name;
this.gpa = gpa;
}
public void printStudent() {
System.out.println(
String.format("Student{name='%s', gpa='%s'}", this.name, this.gpa)
);
}
// Serialization
public static void serialize(Student student, String fileName) throws IOException {
/*
* studnet를 serialization하여
* File fileName에 Write해줍니다.
* */
FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(student);
oos.close();
}
// De-serialization
public static Student deserialize(String fileName) throws IOException, ClassNotFoundException {
/*
* File fileName을 읽고,
* Student로 deserialization합니다.
* */
FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis);
Object obj = ois.readObject();
ois.close();
return (Student) obj;
}
}
Main.java
- Main.java는 다음과 같습니다.
package com.company;
public class Main {
public static void main(String[] args) throws Exception {
Student student = new Student("LSH", 4.3);
student.printStudent();
String fileName = "a.student";
System.out.println("== Serialization");
Student.serialize(student, fileName);
System.out.println("== De-serialization");
Student deserializedStudent = Student.deserialize(fileName);
deserializedStudent.printStudent();
}
}
- 실행결과는 다음과 같습니다.
Student{name='LSH', gpa='4.3'}
== Serialization
== De-serialization
Student{name='LSH', gpa='0.0'}
serialVersionUID
Studentclass를 보면serialVersionUID이 작성되어 있는 것을 알 수 있습니다.- 얘는 일종의 serialization에 대한 버전을 작성하는 놈이죠. 가령
serialVersionUID이 1일 때 object를 serialization하고, 이후 class를 새롭게 정의하고serialVersionUID를 2로 변경했다고 하겠습니다. 그럼serialVersionUID이 1일때 저장해놓은 object를 deserialization할 수 없습니다. 사실 그렇죠. class의 정의 자체가 다른데(변수가 추가되어었다거나), 동일한 방식으로 serialization, deserialization해서는 안되겠죠. - 그러나, 사실 class의 정의가 달라질 경우 타 시스템에 영향을 많이 줄 정도로 민감한 class가 아니라면, 굳이
serialVersionUID값을 작성해둘 필요도 없습니다. 어차피 컴파일러가 알아서 처리해주거든요. 일단은, 그냥 class에 대한 버전을 의미한다, 정도로만 이해하고 있어도 아무 문제가 없습니다.
public static final long serialVersionUID = 1L;
wrap-up
- java가 아닌 환경에도 객체가 사용될 경우에는 XML, json과 같은 다른 serialization방식을 사용하는 것이 좋을 수 있습니다. 요새 json은 거의 de-facto같은 느낌이기도 하구요.
댓글남기기