β μλ° μ§λ ¬ν(Serializable) - μλ²½ λ§μ€ν°νκΈ°
μλ°μ μ§λ ¬ν & μμ§λ ¬ν
μ§λ ¬ν(serialize)λ μλ° μΈμ΄μμ μ¬μ©λλ Object λλ Dataλ₯Ό λ€λ₯Έ μ»΄ν¨ν°μ μλ° μμ€ν μμλ μ¬μ© ν μ μλλ‘ λ°μ΄νΈ μ€νΈλ¦Ό(stream of bytes) ννλ‘ μ°μμ μΈ(serial) λ°μ΄ν°λ‘ λ³ννλ ν¬λ§· λ³ν κΈ°μ μ μΌμ»«λλ€. κ·Έ λ°λ κ°λ μΈ μμ§λ ¬νλ(Deserialize)λ λ°μ΄νΈλ‘ λ³νλ λ°μ΄ν°λ₯Ό μλλλ‘ μλ° μμ€ν μ Object λλ Dataλ‘ λ³ννλ κΈ°μ μ΄λ€.
μ΄λ₯Ό μμ€ν μ μΌλ‘ μ΄ν΄λ³΄λ©΄, JVMμ ν(heap) νΉμ μ€ν(stack) λ©λͺ¨λ¦¬μ μμ£Όνκ³ μλ κ°μ²΄ λ°μ΄ν°λ₯Ό μ§λ ¬νλ₯Ό ν΅ν΄ λ°μ΄νΈ ννλ‘ λ³ννμ¬ λ°μ΄ν°λ² μ΄μ€λ νμΌκ³Ό κ°μ μΈλΆ μ μ₯μμ μ μ₯ν΄λκ³ , λ€λ₯Έ μ»΄ν¨ν°μμ μ΄ νμΌμ κ°μ Έμ μμ§λ ¬νλ₯Ό ν΅ν΄ μλ° κ°μ²΄λ‘ λ³νν΄μ JVM λ©λͺ¨λ¦¬μ μ μ¬νλ κ²μΌλ‘ 보면 λλ€.
[ λ°μ΄νΈ μ€νΈλ¦Ό μ΄λ? ]
μ€νΈλ¦Όμ ν΄λΌμ΄μΈνΈλ μλ² κ°μ μΆλ°μ§ λͺ©μ μ§λ‘ μ μΆλ ₯νκΈ° μν λ°μ΄ν°κ° νλ₯΄λ ν΅λ‘λ₯Ό λ§νλ€.
μλ°λ μ€νΈλ¦Όμ κΈ°λ³Έ λ¨μλ₯Ό λ°μ΄νΈλ‘ λκ³ μκΈ° λλ¬Έμ, λ€νΈμν¬, λ°μ΄ν°λ² μ΄μ€λ‘ μ μ‘νκΈ° μν΄ μ΅μ λ¨μμΈ λ°μ΄νΈ μ€νΈλ¦ΌμΌλ‘ λ³ννμ¬ μ²λ¦¬νλ€.
μ§λ ¬ν μ¬μ©μ²
μ§λ ¬νλ₯Ό μμ©νλ€λ©΄ νλ°μ±μ΄ μλ μΊμ± λ°μ΄ν°λ₯Ό μꡬ μ μ₯μ΄ νμν λ μ¬μ©ν μλ μλ€.
μλ₯Όλ€μ΄ JVMμ λ©λͺ¨λ¦¬μμλ§ μμ£Όλμ΄μλ κ°μ²΄ λ°μ΄ν°κ° μμ€ν μ΄ μ’ λ£λλλΌλ λμ€μ λ€μ μ¬μ¬μ©μ΄ λ μ μμλ μμν(Persistence)λ₯Ό ν΄λλ©΄ μ’λ€. μ΄λ¬ν νΉμ±μ μ΄λ¦° μλ° μ§λ ¬νλ μ€μ λ‘λ μ¬λ¬κ³³μ μμ©λλ€. λͺκ°μ§ μ΄ν΄λ³΄λ©΄ λ€μκ³Ό κ°λ€.
μλΈλ¦Ώ μΈμ (Servlet Session)
- λ¨μν μΈμ μ μλΈλ¦Ώ λ©λͺ¨λ¦¬ μμμ μ΄μ©νλ€λ©΄ μ§λ ¬νλ₯Ό νμλ‘ νμ§ μμ§λ§, λ§μΌ μΈμ λ°μ΄ν°λ₯Ό μ μ₯ & 곡μ κ° νμν λ μ§λ ¬νλ₯Ό μ΄μ©νλ€.
- μΈμ λ°μ΄ν°λ₯Ό λ°μ΄ν°λ² μ΄μ€μ μ μ₯ν λ
- ν°μΊ£μ μΈμ ν΄λ¬μ€ν°λ§μ ν΅ν΄ κ° μλ²κ°μ λ°μ΄ν° 곡μ κ° νμν λ
μΊμ (Cache)
- λ°μ΄ν°λ² μ΄μ€λ‘λΆν° μ‘°νν κ°μ²΄ λ°μ΄ν°λ₯Ό λ€λ₯Έ λͺ¨λμμλ νμν λ μ¬μ°¨ DBλ₯Ό μ‘°ννλ κ²μ΄ μλ, κ°μ²΄λ₯Ό μ§λ ¬ννμ¬ λ©λͺ¨λ¦¬λ μΈλΆ νμΌμ μ μ₯ν΄ λμλ€κ° μμ§λ ¬ννμ¬ μ¬μ©νλ μΊμ λ°μ΄ν°λ‘μ μ΄μ©μ΄ κ°λ₯νλ€.
- λ¬Όλ‘ μλ° μ§λ ¬νλ₯Ό μ΄μ©ν΄μλ§ μΊμλ₯Ό μ μ₯ν μ μλ κ²μ μλμ§λ§ μλ° μμ€ν μμ λ§νΌμ ꡬνμ΄ κ°μ₯ κ°νΈνκΈ° λλ¬Έμ λ§μ΄ μ¬μ©λλ€κ³ 보면 λλ€.
- λ¨, μμ¦μ Redis, Memcached μ κ°μ μΊμ DBλ₯Ό λ§μ΄ μ¬μ©νλ νΈμ΄λ€.
μλ° RMI (Remote Method Invocation)
- μλ° RMIλ μ격 μμ€ν κ°μ λ©μμ§ κ΅νμ μν΄μ μ¬μ©νλ μλ°μμ μ§μνλ κΈ°μ μ΄λ€.
- μ΄ λ©μΈμ§μ κ°μ²΄ λ°μ΄ν°λ₯Ό μ§λ ¬ννμ¬ μ‘μ νλ κ²μ΄λ€.
- μ΅κ·Όμλ μμΌμ μ΄μ©νκΈ° λλ¬Έμ μμ°μ΄λ κΈ°μ μ΄λ€.
μ§λ ¬ν vs JSON λΉκ΅
μ΄μ²λΌ μλ° μ§λ ¬νλ μΈλΆ νμΌμ΄λ λ€νΈμν¬λ₯Ό ν΅ν΄ ν΄λΌμ΄μΈνΈ κ°μ κ°μ²΄ λ°μ΄ν°λ₯Ό μ£Όκ³ λ°μ λ μ¬μ©λλ€.
κ·Έλ°λ° μ΄λ―Έ κ°λ°μ μ‘°κΈ ν΄λ³΄μ λ μλΆλ€μ΄λΌλ©΄ λ¬Έλ μ΄λ° μκ°μ΄ λ€ κ²μ΄λ€. CSV, JSON μ΄λΌλ νλ₯ν λ°μ΄ν° ν¬λ§·μ΄ μλλ° κ΅³μ΄ μ§λ ¬νκ° νμνλλλΌλ μλ¬Έμ μ΄λ€.
μ€μ λ‘ JSONμ μΉ(Web) λΏλ§ μλλΌ κ²μ μͺ½μμλ μ€μ νμΌλ‘ μ°μ΄κ±°λ λ°μ΄ν°λ₯Ό κ΅νν λ λ²μ©μ μΌλ‘ μ¬μ©λλ€. κ·Έλ¦¬κ³ μ§λ ¬νλ μ€λ‘μ§ μλ° νλ‘κ·Έλ¨μμλ§ μ¬μ©μ΄ κ°λ₯νμ§λ§, JSON ννλ‘ κ°μ²΄ λ°μ΄ν°λ₯Ό μ μ₯ν΄λλ©΄ νμ΄μ¬, μλ°μ€ν¬λ¦½νΈμμλ λ²μ©μ μΌλ‘ μ¬μ©μ΄ κ°λ₯νλ€.
κ·Έλ λ€λ©΄ κ·Έλ₯ JSONμ μ΄μ©νλ©΄ λμ§ κ΅³μ΄ μ§λ ¬νλ₯Ό 곡λΆν΄μ μ¬μ©ν΄μΌ νλ μ΄μ κ° λκ° μμκΉ?
μ΄μ λν΄μ λ¨Όμ μλ° μ§λ ¬νμ μ₯μ μ λν΄ μμ보μλ©΄ λ€μκ³Ό κ°λ€.
μλ° μ§λ ¬ν μ₯μ
첫λ²μ§Έλ, μ§λ ¬νλ μλ°μ κ³ μ κΈ°μ μΈ λ§νΌ λΉμ°ν μλ° μμ€ν μμ κ°λ°μ μ΅μ νλμ΄ μλ€.
λλ²μ§Έλ, μλ°μ κ΄νν λ νΌλ°μ€ νμ μ λν΄ μ μ½ μμ΄ μΈλΆμ λ΄λ³΄λΌ μ μλ€λ κ²μ΄λ€.
μλ₯Όλ€μ΄ κΈ°λ³Έν(int, double, string) νμ μ΄λ λ°°μ΄(array)κ³Ό κ°μ νμ λ€μ μ λ§ν νλ‘κ·Έλλ° μΈμ΄κ° 곡ν΅μ μΌλ‘ μ¬μ©νλ νμ μ΄κΈ° λλ¬Έμ, μ΄λ¬ν κ°λ€μ JSON μΌλ‘λ μΆ©λΆν μνΈ μ΄μ©μ΄ κ°λ₯νλ€.
νμ§λ§ μλ°μ μ¨κ° 컬λ μ μ΄λ ν΄λμ€, μΈν°νμ΄μ€ νμ λ€μ μ΄λ¨κΉ? νΉμ μ¬μ©μκ° μ»€μ€ν μΌλ‘ μλ£ν νμ μ λ§λ€μ΄ μ¬μ©νκ³ μλ κ²½μ°, λ¨μ νμΌ ν¬λ§·λ§μΌλ‘λ νμ κ°―μκ° νκ³κ° μλ€. κ·Έλμ μ΄λ€μ μΈλΆμ λ΄λ³΄λ΄κΈ° μν΄μ κ° λ°μ΄ν°λ₯Ό 맀μΉμν€λ λ³λμ νμ±(parsing)μ΄ νμνλ€.
κ·Έμ λ°ν΄, μ§λ ¬νλ₯Ό μ΄μ©νλ©΄ λΉλ‘ νμ΄μ¬μ΄λ μλ°μ€ν¬λ¦½νΈμ κ°μ λ€λ₯Έ μμ€ν μμλ μ¬μ©νμ§λ λͺ»ν μ§λΌλ, μ§λ ¬ν κΈ°λ³Έ μ‘°κ±΄λ§ μ§ν¨λ€λ©΄ νλν μμ μμ΄ κ·Έλ₯ λ°λ‘ μΈλΆμ 보λΌμκ° μλ€. κ·Έλ¦¬κ³ μμ§λ ¬νλ₯Ό ν΅ν΄ μ½μ΄λ€μ΄λ©΄ λ°μ΄ν° νμ μ΄ μλμΌλ‘ λ§μΆ°μ§κΈ° λλ¬Έμ μλ° ν΄λμ€μ κΈ°λ₯λ€μ 곧λ°λ‘ λ€μ μ΄μ©ν μ μλ κ²μ΄λ€. λ³λ€λ₯Έ νμ± μμ΄ λ§μ΄λ€. κ·Έλμ μ§λ ¬νλ λ¬Έμμ΄μ λ°μ΄ν°λ² μ΄μ€μ μ μ₯ν΄λκ³ κΊΌλ΄ μ°κΈ°λ νλ€.
μ΄λ¬ν μ§λ ¬νμ κ³ μ ν μ₯μ λ€μ΄ μμ§λ§, λ°λ©΄μ μΉλͺ μ μΈ λ¨μ λ€λ μ‘΄μ¬νλ€. (μ΄λ ν¬μ€ν λ§μ§λ§μμ λ€λ€λ³Έλ€)
κ·Έλ¦¬κ³ μμ¦μ λ²μ©μ μΈ JSONμ μ΄μ©νλ μΆμΈκ° μ μ λκ³ μλ€. λ°λΌμ JSON μ΄λ μ§λ ¬ν μ΄λ μ λν λͺ νν μ λ΅μ μκ³ 'λͺ©μ μ λ°λΌ μ μ ν μ¨μΌ νλ€' μ λλ‘ μ 리ν μ μμ κ² κ°λ€.
μλ° μ§λ ¬ν μ¬μ©λ²
κ°μ²΄ μ§λ ¬ν & μμ§λ ¬ν νκΈ°
Serializable μΈν°νμ΄μ€
μ°μ κ°μ²΄λ₯Ό μ§λ ¬ννκΈ° μν΄μ java.io.Serializable μΈν°νμ΄μ€λ₯Ό implements ν΄μΌ λλ€. κ·Έλ μ§ μμΌλ©΄ NotSerializableException λ°νμ μμΈκ° λ°μλλ€.
Serializable μΈν°νμ΄μ€λ μλ¬΄λ° λ΄μ©λ μλ λ§μ»€ μΈν°νμ΄μ€ λ‘μ, μ§λ ¬νλ₯Ό κ³ λ €νμ¬ μμ±ν ν΄λμ€μΈμ§λ₯Ό νλ¨νλ κΈ°μ€μΌλ‘ μ¬μ©λλ€.
import java.io.Serializable;
class Customer implements Serializable {
int id; // κ³ κ° μμ΄λ
String name; // κ³ κ° λλ€μ
String password; // κ³ κ° λΉλ°λ²νΈ
int age; // κ³ κ° λμ΄
public Customer(int id, String name, String password, int age) {
this.id = id;
this.name = name;
this.password = password;
this.age = age;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", password='" + password + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
ObjectOutputStream κ°μ²΄ μ§λ ¬ν
μ§λ ¬ν(μ€νΈλ¦Όμ κ°μ²΄λ₯Ό μΆλ ₯) μλ ObjectOutputStreamμ μ¬μ©νλ€.
κ°μ²΄κ° μ§λ ¬νλ λ μ€μ§ κ°μ²΄μ μΈμ€ν΄μ€ νλκ° λ§μ μ μ₯νλ€. static νλλ λ©μλλ μ§λ ¬ννμ¬ μ μ₯νμ§ μλλ€.
μλ μ½λλ μΈλΆ νμΌμ κ°μ²΄λ₯Ό μ§λ ¬ννμ¬ μ μ₯νλ μμ μ΄λ€.
public static void main(String[] args) {
// μ§λ ¬νν κ³ κ° κ°μ²΄
Customer customer = new Customer(1, "νκΈΈλ", "123123", 40);
// μΈλΆ νμΌλͺ
String fileName = "Customer.ser";
// νμΌ μ€νΈλ¦Ό κ°μ²΄ μμ± (try with resource)
try (
FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream out = new ObjectOutputStream(fos)
) {
// μ§λ ¬ν κ°λ₯ κ°μ²΄λ₯Ό λ°μ΄νΈ μ€νΈλ¦ΌμΌλ‘ λ³ννκ³ νμΌμ μ μ₯
out.writeObject(customer);
} catch (IOException e) {
e.printStackTrace();
}
}
μ½λλ₯Ό μ€ννλ©΄ Customer.ser νμΌμ΄ μμ±λλ€. νμΌμ .ser νμ₯λͺ μ μ¬μ©νλλ°, .txt λ‘ ν΄λ λ¬Έμ μλ€. λ€λ§ μ§λ ¬νλ νμΌμ΄λΌλ κ²μ λͺ μνλ κ²μ΄ μ’κΈ° λλ¬Έμ λ€μ΄λ°μ .ser μ΄λ .obj λ‘ λ§μ΄ μ§μ νλ νΈμ΄λ€.
κ·Έλ¦¬κ³ νμΌ λ΄μ©μ 보면 μ¬λμ΄ μ½μ μ μλ λ¬Έμ ννλ‘ λμ΄μλ κ±Έ λ³Ό μ μλ€.
ObjectInputStream κ°μ²΄ μμ§λ ¬ν
μμ§λ ¬ν(μ€νΈλ¦ΌμΌλ‘λΆν° κ°μ²΄λ₯Ό μ λ ₯)μλ ObjectInputStreamμ μ¬μ©νλ€.
λ¨, μμ§λ ¬ν ν λ μ£Όμμ¬νμ΄ μλλ°, μ§λ ¬ν λμμ΄ λ κ°μ²΄μ ν΄λμ€κ° μΈλΆ ν΄λμ€λΌλ©΄, ν΄λμ€ κ²½λ‘(Class Path)μ μ‘΄μ¬ν΄μΌ νλ©° import λ μνμ¬μΌ νλ€.
μλ μ½λλ μΈλΆ νμΌμ μ½μ΄ μμ§λ ¬ννμ¬ λ€μ μλ° κ°μ²΄ν νλ μμ μ΄λ€.
public static void main(String[] args) {
// μΈλΆ νμΌλͺ
String fileName = "Customer.ser";
// νμΌ μ€νΈλ¦Ό κ°μ²΄ μμ± (try with resource)
try(
FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream in = new ObjectInputStream(fis)
) {
// λ°μ΄νΈ μ€νΈλ¦Όμ λ€μ μλ° κ°μ²΄λ‘ λ³ν (μ΄λ μΊμ€ν
μ΄ νμ)
Customer deserializedCustomer = (Customer) in.readObject();
System.out.println(deserializedCustomer);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
μ΄λ κ² μμ§λ ¬νλ₯Ό μ΄μ©νκ²λλ©΄, μ§λ ¬νλ μΈλΆ νμΌλ§ μμΌλ©΄ μμ±μλ‘ κ°μ²΄ μ΄κΈ°ν μμ΄ λ°λ‘ κ°μ²΄μ μ 보λ₯Ό κ°μ Έμ μΈμ€ν΄μ€ν νμ¬ μ¬μ©ν μ μκ² λλ λ§λ² κ°μ κΈ°λ₯μ μ»μ μ μκ² λλ€.
μ§λ ¬ν κ°μ²΄λ₯Ό 리μ€νΈλ‘ κ΄λ¦¬
λ§μ½ μ¬λ¬κ°μ κ°μ²΄λ₯Ό μ§λ ¬ννκ³ μ΄λ₯Ό μμ§λ ¬ν νλ€λ©΄ μ£Όμν΄μΌν μ¬νμ΄ μλ€.
μμ§λ ¬ν ν λλ μ§λ ¬νν λμ μμμ μΌμΉ ν΄μΌ λλ€λ μ μΈλ°, μλ₯Όλ€μ΄ κ°μ²΄ customer1, customer2, customer3 μμλ‘ μ§λ ¬ν νλ€λ©΄, μμ§λ ¬ν ν λλ customer1, customer2, customer3 μ μμλ‘ λ°μμΌ λλ€. (νμΌμ μ§λ ¬ν μμλλ‘ λ°μ΄νΈ λ¬Έμκ° κΈ°μ¬λμ΄ μ§λ λΉμ°ν μ리μ΄κΈ΄ νλ€)
λ°λΌμ μ§λ ¬νν κ°μ²΄κ° λ§λ€λ©΄ ArrayListμ κ°μ 컬λ μ μ μ μ₯ν΄μ κ΄λ¦¬ νλκ²μ΄ μ’λ€. ArrayList νλλ§ μμ§λ ¬ννλ©΄ λλ―λ‘ κ°μ²΄μ μμλ₯Ό κ³ λ €ν νμκ° μμ΄μ§κΈ° λλ¬Έμ΄λ€. μ΄λ μμ 'μ§λ ¬νμ JSON λΉκ΅ ννΈ'μμ μ§λ ¬νμ μ₯μ μ λν΄ μκ°ν λ μλ° κ³ μ μ ν΄λμ€, μΈν°νμ΄μ€λ₯Ό κ³ λλ‘ μ§λ ¬ν / μμ§λ ¬νν μ μλ€κ³ λ§ν λ° μλ€.
public static void main(String[] args) throws IOException, ClassNotFoundException {
// μ§λ ¬νν κ³ κ° κ°μ²΄
Customer hongildong = new Customer(1, "νκΈΈλ", "123123", 40);
Customer sejong = new Customer(2, "μΈμ’
λμ", "4556456", 55);
Customer jumong = new Customer(3, "μ£Όλͺ½", "789789", 25);
// μΈλΆ νμΌλͺ
String fileName = "Customer.ser";
// 리μ€νΈ μμ±
List<Customer> customerList = new ArrayList<>();
customerList.add(hongildong);
customerList.add(sejong);
customerList.add(jumong);
// 리μ€νΈ μ체λ₯Ό μ§λ ¬ν νκΈ°
FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(customerList);
out.close();
// μμ§λ ¬ν νμ¬ λ¦¬μ€νΈ κ°μ²΄μ λ£κΈ°
FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream in = new ObjectInputStream(fis);
List<Customer> deserializedCustomerList = (List<Customer>) in.readObject();
in.close();
System.out.println(deserializedCustomerList);
}
μ§λ ¬ν μμ μ μΈ
κ°μ²΄μ λͺ¨λ μΈμ€ν΄μ€λ₯Ό μ§λ ¬ννκΈ°μλ λ무 무κ²κ±°λ νΉμ μ€μν μ 보λ μΈλΆμ λ ΈμΆμν€κ³ μΆμ§ μμ κ²½μ°, μ§λ ¬νν μμλ₯Ό μ§μ μ νν νμκ° μλ€.
transient ν€μλ
κ°λ¨νκ² λ³μ μ μλ¬Έ μμ transient ν€μλλ₯Ό λͺ μν΄μ£Όλ©΄ μμμ μ§λ ¬ν λμμμ μ μΈ λλλ‘ ν μ μλ€. transientκ° λΆμ μΈμ€ν΄μ€ λ³μμ κ°μ κ·Έ νμ μ κΈ°λ³Έκ°μΌλ‘ μ§λ ¬ν λλ€.
- Primitive νμ : κ° νμ μ λν΄νΈ κ° (intλ 0)
- Reference νμ : null
λ¨, μ§λ ¬ν λμμμ μ μΈνλλ° μμ΄ κ·Έ λ°μ΄ν°κ° κ°μ²΄μ μ€μ λ‘ νμκ° μλμ§, μ μΈνμμ κ²½μ°μ μλΉμ€ μ₯μ μ μ΄μμ΄ μλμ§μ λν κ³ λ €λ₯Ό ν΄μΌνλ€.
class Customer implements Serializable {
int id;
String name;
transient String password; // μ§λ ¬ν λμμμ μ μΈ
int age;
public Customer(int id, String name, String password, int age) {
this.id = id;
this.name = name;
this.password = password;
this.age = age;
}
...
}
컀μ€ν μ§λ ¬ν
readObject / writeObject μ¬μ μ
μ§λ ¬ν & μμ§λ ¬νν λ νΈμΆλλ readObject() μ writeObject() λ κΈ°λ³Έμ μΌλ‘ λͺ¨λ μμμ λν΄ μλ μ§λ ¬ν νλ€. κ·Έλ°λ° μ΄ λ©μλλ€μ μ§λ ¬νν ν΄λμ€μ λ³λλ‘ μ¬μ μ ν΄μ£Όλ©΄ μ§λ ¬νλ₯Ό μ νμ μΌλ‘ μ‘°μν μ μκ² λλ€. μ΄λ₯Ό 컀μ€ν
μ§λ ¬ν λΌκ³ λ λΆλ¦¬μ΄λ€.
μλ₯Όλ€μ΄ Customer ν΄λμ€μ λΉλ°λ²νΈ νλκ°μ λ―Όκ°ν μ λ³΄λΌ μ§λ ¬ννμ§ μκ² λ€νλ©΄, writeObject λ©μλμμ password νλ λΆλΆλ§ λΉΌκ³ μ°κΈ° λμμ νλλ‘ μ¬μ μ ν΄μ€ μ μλ€. μ΄μΈμλ μμΈν 쑰건문μ΄λ λ‘μ§μ κ°λ―Έν΄μ μ§λ ¬νλ₯Ό 컀μ€ν μ‘°μ ν μ μλ€.
class Customer implements Serializable {
int id; // κ³ κ° μμ΄λ
String name; // κ³ κ° λλ€μ
String password; // κ³ κ° λΉλ°λ²νΈ
int age; // κ³ κ° λμ΄
public Customer(int id, String name, String password, int age) {
this.id = id;
this.name = name;
this.password = password;
this.age = age;
}
// μ§λ ¬ν λμ μ¬μ μ
private void writeObject(ObjectOutputStream out) throws IOException{
out.writeInt(id);
out.writeObject(name);
out.writeInt(age);
}
// μμ§λ ¬ν λμ μ¬μ μ
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
this.id = in.readInt();
this.name = (String) in.readObject();
this.age = in.readInt();
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", password='" + password + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Customer user = new Customer(1, "νκΈΈλ", "123123", 40);
String fileName = "Customer.ser";
// μ§λ ¬ν νκΈ° (νμ€λ‘ νν)
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
out.writeObject(user);
out.close();
// μμ§λ ¬ν νκΈ° (νμ€λ‘ νν)
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(fileName)));
Customer deserialized = (Customer) in.readObject();
in.close();
System.out.println(deserialized);
}
κ°μ²΄ μμ κ΄κ³μμμ μ§λ ¬ν
λ§μ½ λΆλͺ¨-μμ μμ κ΄κ³μμ λΆλͺ¨ ν΄λμ€κ° Serializableμ ꡬννλ€λ©΄ μμ ν΄λμ€λ Serializableμ ꡬννμ§ μμλ μ§λ ¬νκ° κ°λ₯νλ€. κ·Έλ¬λ©΄ λ°λλ‘ λΆλͺ¨ ν΄λμ€λ Serializableμ ꡬννμ§ μκ³ μμ ν΄λμ€λ§ ꡬννλ€λ©΄ μ΄λ€ λ°©μμΌλ‘ μ§λ ¬νλ κΉ?
μ§λ ¬νν λ λΆλͺ¨ ν΄λμ€μ μΈμ€ν΄μ€ νλλ 무μλκ³ μμ νλλ§ μ§λ ¬νκ° λλ€. λ°λΌμ μμ ν΄λμ€μ νλκΉμ§ μ§λ ¬ννλ €λ©΄ λΆλͺ¨ ν΄λμ€κ° Serializableμ ꡬννλλ‘ μ€μ νλμ§, μμμ λ€λ€λ³Έ writeObject / readObject λ©μλλ₯Ό μ¬μ μνμ¬ μ§μ μ§λ ¬ν μ½λλ₯Ό μΆκ° νλ©΄ λλ€.
μλ₯Ό λ€μ΄ UserInfo ν΄λμ€κ° UserAccountλ₯Ό μμνλλ°, UserInfo ν΄λμ€μλ§ Serializableμ΄ κ΅¬νλμ΄μλ€κ³ νμ. UserAccount λΆλͺ¨ ν΄λμ€μ νλκΉμ§ μ§λ ¬ννκ³ μΆλ€λ©΄ UserAccountμ μ§λ ¬ν λ©μλλ₯Ό μ¬μ μ ν΄μ£Όκ³ μΆκ°λ‘ μ§λ ¬νν λΆλΆμ κΈ°μ¬νλ©΄ λλ€.
class UserAccount {
String name;
String password;
// ! κΈ°λ³Έ μμ±μ μμΌλ©΄ InvalidClassException : no valid constructor λ°μ
public UserAccount() {
}
UserAccount(String name, String password) {
this.name = name;
this.password = password;
}
}
class UserInfo extends UserAccount implements Serializable {
int age;
int height;
boolean marreid;
UserInfo(String name, String password, int age, int height, boolean marreid) {
super(name, password);
this.age = age;
this.height = height;
this.marreid = marreid;
}
private void writeObject(ObjectOutputStream out) throws IOException {
// λΆλͺ¨ νλ μ§λ ¬ν
out.writeUTF(name);
out.writeUTF(password);
// μμ νλ μ§λ ¬ν (λ©μλλ₯Ό ν΅ν΄ νλ²μ μ²λ¦¬)
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
// λΆλͺ¨ νλ μμ§λ ¬ν
name = in.readUTF();
password = in.readUTF();
// μμ νλ μμ§λ ¬ν (λ©μλλ₯Ό ν΅ν΄ νλ²μ μ²λ¦¬)
in.defaultReadObject();
}
@Override
public String toString() {
return "UserInfo{" +
"age=" + age +
", height=" + height +
", marreid=" + marreid +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
UserInfo u1 = new UserInfo("νκΈΈλ", "123123", 33, 170, true);
UserInfo u2 = new UserInfo("μκΊ½μ ", "456456", 12, 180, false);
String fileName = "UserInfo.ser";
// μ§λ ¬ν
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
out.writeObject(u1);
out.writeObject(u2);
out.close();
// μμ§λ ¬ν
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(fileName)));
// κ°μ²΄λ₯Ό μ½μλλ μΆλ ₯ν μμμ μΌμΉ
UserInfo u3 = (UserInfo) in.readObject();
UserInfo u4 = (UserInfo) in.readObject();
System.out.println(u3);
System.out.println(u4);
in.close();
}
μλ° μ§λ ¬ν λ²μ κ΄λ¦¬
SerialVersionUID
Serializable μΈν°νμ΄μ€λ₯Ό ꡬννλ λͺ¨λ μ§λ ¬νλ ν΄λμ€λ serialVersionUID(μ΄ν SUID) μ΄λΌλ κ³ μ μλ³λ²νΈλ₯Ό λΆμ¬ λ°λλ€. μ΄ μλ³ IDλ ν΄λμ€λ₯Ό μ§λ ¬ν, μμ§λ ¬ν κ³Όμ μμ λμΌν νΉμ±μ κ°λμ§ νμΈνλλ° μ¬μ©λλ€. κ·Έλμ ν΄λμ€ λ΄λΆ ꡬμ±μ΄ μμ λ κ²½μ°, κΈ°μ‘΄μ μ§λ ¬νν SUIDμ νμ¬ ν΄λμ€μ SUID λ²μ μ΄ λ€λ₯΄κΈ° λλ¬Έμ μ΄λ₯Ό μΈμ§νκ³ InvalidClassException μμΈκ° λ°μμμΌ κ° λΆμΌμΉ λλ νμμ λ―Έμ°μ λ°©μ§νλ€.
λ¨, μ§λ ¬ν μ€ν μ serialVersionUID κ° λͺ μλ νμκ° μλλ©°, λ§μΌ ν΄λμ€μ SUID νλλ₯Ό λͺ μνμ§ μλλ€λ©΄, μμ€ν μ΄ λ°νμμ ν΄λμ€μ μ΄λ¦, μμ±μ λ±κ³Ό κ°μ΄ ν΄λμ€μ ꡬ쑰λ₯Ό μ΄μ©ν΄ μνΈ ν΄μν¨μλ₯Ό μ μ©ν΄ μλμΌλ‘ ν΄λμ€ μμ μμ±νκ² λλ€.
μλ₯Όλ€μ΄ λ€μ Member ν΄λμ€λ₯Ό μ§λ ¬νμμΌ Member.ser νμΌλ‘ μ μ₯νκ³ μλΉμ€μμ μ΄λ₯Ό κ°μ Έμ μμ§λ ¬ννμ¬ μ¬μ©νλ€κ³ κ°μ ν΄λ³΄μ.
class Member implements Serializable {
private String name;
private int age;
private String address;
...
}
κ·Έλ°λ° Member ν΄λμ€μ μ΄λ©μΌ νλλ₯Ό μΆκ°ν΄μΌ νλ€λ λͺ μΈμκ° μλ€. κ·Έλμ Member ν΄λμ€μ email μΈμ€ν΄μ€ νλλ₯Ό μΆκ°νμκ³ νμμ²λΌ νλ‘κ·Έλ¨μ μ€νμμΌ°λ€.
class Member implements Serializable {
private String name;
private int age;
private String address;
private String email; // μλ‘ μΆκ°ν ν΄λμ€ κ΅¬μ± μμ
...
}
κ·Έλ¬λ κ²°κ³Όλ μμ κ°μ μλ»κ±΄ μλ¬κ° μ°λ¦¬λ₯Ό λ°κ²¨μ€ κ²μ΄λ€.
μμ μμ μμλ μ§λ ¬ν ν΄λμ€λ₯Ό μ μΈν λ SUID κ°μ μλ΅νμ§λ§ λ΄λΆμ μΌλ‘ μλ³λ²νΈκ° μμ±λμ΄ μμ΄ λμ€μ ν΄λμ€λ₯Ό μμ νκ² λλ€λ©΄ SUID κ°λ λ³νκ² λμ΄ μμ§λ ¬νμ μ€λ₯κ° μκΈ°λ κ²μ΄λ€.
ν΄λμ€ λ²μ μλ κ΄λ¦¬
λ§μΌ λ€νΈμν¬λ‘ κ°μ²΄λ₯Ό μ§λ ¬ννμ¬ μ μ‘νκ±°λ νμ μ νλ κ²½μ° μμ μμ μ‘μ μ λͺ¨λ κ°μ λ²μ μ ν΄λμ€λ₯Ό κ°μ§κ³ μμ΄μΌ ν ν λ°, λ§μΌ ν΄λμ€κ° μ‘°κΈλ§ λ³κ²½μ¬νμ΄ μμΌλ©΄ λͺ¨λ μ¬μ©μμκ² μ¬λ°°ν¬ν΄μΌ νλ μ λ‘μ¬νμ΄ μ겨 νλ‘κ·Έλ¨μ κ΄λ¦¬νκΈ° μ΄λ ΅κ² λ§λ λ€.
λ°λΌμ μ§λ ¬ν ν΄λμ€λ μ λ§ν μν©μμ serialVersionUID λ₯Ό μ§μ λͺ μν΄μ£Όμ΄ ν΄λμ€ λ²μ μ μλμΌλ‘ κ΄λ¦¬νλ κ²μ κΆμ₯νλ νΈμ΄λ€. SUIDλ₯Ό μ§μ λͺ μν΄μ£Όλ©΄ ν΄λμ€μ λ΄μ©μ΄ λ³κ²½λμ΄λ, ν΄λμ€μ λ²μ μ΄ μμ€ν μ΄ μλ μμ±λ κ°μΌλ‘ λ³κ²½λμ§ μκΈ° λλ¬Έμ΄λ€. μ΄μΈμλ λ°νμμ SUIDλ₯Ό μμ±νλ μκ°λ λ§μ΄ μ‘μλ¨ΉκΈ° λλ¬Έμ 미리 λͺ μλ₯Ό κ°λ ₯ν κΆμ₯λλ λ°μ΄λ€.
serialVersionUID λ μλμ κ°μ΄ private static final μ μ΄μλ‘ μ μΈν΄μΌ νλ©° νμ μ long μ΄λ€.
class Member implements Serializable {
// serialVersionUID κΌ λͺ
μ ν κ²
private static final long serialVersionUID = 123L;
private String name;
private int age;
private String address;
// private String email; // μλ‘ μΆκ°ν ν΄λμ€ κ΅¬μ± μμ
...
}
μ΄μ SUIDλ₯Ό μ μΈν Member ν΄λμ€λ₯Ό μ§λ ¬ννμ¬ μΈλΆ νμΌλ‘ μΆμΆνκ³ , email νλλ₯Ό ν΄λμ€μ μλ‘ μΆκ°νκ³ μμ§λ ¬ν ν΄λ³΄μ. κ·Έλ¬λ©΄ email νλλ μμμ μ μΈ(nullλ‘ μ΄κΈ°ν)λκ³ μμ§λ ¬νλ¨μ λ³Ό μ μλ€.
μ΄λ κ² ν΄λμ€ λ΄μ serialVersionUIDλ₯Ό μ μν΄μ£Όλ©΄, ν΄λμ€μ λ΄μ©μ΄ λ°λμ΄λ ν΄λμ€μ λ²μ μ΄ μ μ§λ¨μΌλ‘, λΉλ‘ νλκ° λ§€μΉλμ§ μλλΌλ μΌλ¨μ μμ§λ ¬ν λμ μ체λ ννλλ‘ ν μ μλ€.
SerialVersionUID μλ μμ±νκΈ°
serialVersionUIDλ μ μκ°μ΄λΌ μ΄λ ν κ°μΌλ‘λ μ§μ ν μ μμ§λ§, λ¨μν κ°μ΄λ©΄ κ²ΉμΉ μ°λ €κ° μκΈ° λλ¬Έμ μλ‘ λ€λ₯Έ ν΄λμ€κ°μ κ°μ κ°μ κ°μ§ μλλ‘ serialversion κ°μ μμ±ν΄μ£Όλ νλ‘κ·Έλ¨μ μ¬μ©νλ κ²μ΄ μ’λ€.
JVMμ μ€μΉν λ κ°μ΄ μ€μΉλλ serialver.exeλ₯Ό μ¬μ©ν΄μ μμ±λ κ°μ μ΄μ©ν μ μμ§λ§ λ²κ±°λ‘μ°λ―λ‘, IntelliJλ₯Ό μ΄μ©ν΄ κ°λ¨ν μ€μ λ§μΌλ‘ ν΄λ¦ νλ² λ§μΌλ‘ SUID κ°μ μμ±ν΄ μ€ μ μλ λ°©λ²μ μκ°ν΄λ³Έλ€.
SerialVersionUID μλ κ΄λ¦¬ μ μμ¬ν
ν΄λμ€ serialVersionUIDλ₯Ό λͺ μνλλΌλ μ λ λ§λ₯μ΄ μλλ€. μμ κ°μ΄ λ¨μν νλ λ³μ νλ μΆκ°νλ μ λλ λ¬Έμ κ° μκ² μ§λ§ νλ νμ μ λ³κ²½νλ μν©μμλ λ²μ μλ κ΄λ¦¬λ₯Ό νμ¬λ μμΈλ₯Ό λ§μμ μλ€.
μλ₯Όλ€μ΄ Member ν΄λμ€μ ageλ₯Ό int ν μμ long νμΌλ‘ μ λ°μ΄νΈνκ³ μμ§λ ¬νλ₯Ό ν΄λ³΄λ©΄ μλμ κ°μ΄ incompatible type μλ¬κ° λ°μνκ² λλ€.
μλ°μμ μ§λ ¬νλ₯Ό μ¬μ©ν λ μμΈκ° λ°μνκ±°λ μ£Όμ ν΄μΌ νλ μν©μ μ 리ν΄λ³΄λ©΄ λ€μκ³Ό κ°λ€.
- λ©€λ² λ³μλ₯Ό μΆκ°ν λ (μν₯ μμ - κΈ°λ³Έκ°μΌλ‘ μ€μ )
- λ©€λ² λ³μκ° μμ λ λ (μν₯ μμ)
- λ©€λ² λ³μμ μ΄λ¦μ΄ λ°λ λ (μν₯ μμ - κ°μ΄ ν λΉλμ§ μμ)
- λ©€λ² λ³μμ μ κ·Ό μ μ΄μ λ³κ²½ (μν₯ μμ)
- λ©€λ² λ³μμ νμ μ΄ λ°λ λ (μν₯ μμ)
- λ©€λ² λ³μμ static μ transient μΆκ° (μν₯ μμ)
μμ μ£Όμμ¬νμ 보면 νλ νμ λ³κ²½λ§ μ‘°μ¬νλ©΄ λ κ² κ°μ§λ§, μ¬μ€ μ§λ ¬νλ₯Ό μ¬μ©ν λλ μμ£Ό λ³κ²½λ μμ§κ° μλ ν΄λμ€μ κ°μ²΄λ κ·Έλ₯ μ§λ ¬νλ₯Ό μ¬μ©νμ§ μλ κ²μ΄ μ’λ€. μΆν λ²μ μμ μ΄μ λ²μ μ μν₯μμ΄ μμ€ μ½λλ₯Ό μμ νλ κ²μ λ§€μ° μ΄λ ΅κΈ° λλ¬Έμ΄λ€.
μλ° μ§λ ¬ν μμΈ
InvalidClassException
InvalidClassException μμΈλ μ§λ ¬νλ₯Ό μ΄μ©νλ€λ³΄λ©΄ νν μ ν μ μλ μ€λ₯μ΄λ€. μ΄ μμΈλ μλ 3κ°μ§ μ£Όμ μμΈμΌλ‘ μΈν΄ Serialized λλ Deserialized ν μ μλ€λ κ²μ μλ―Ένλ€.
- ν΄λμ€μ SerialVersionUID λ²μ μ΄ λ€λ₯Έ κ²½μ°
- ν΄λμ€μ λ€λ₯Έ λ°μ΄ν° νμ μ ν¬ν¨ν κ²½μ°
- κΈ°λ³Έ μμ±μκ° μλ κ²½μ°
μ΄μ€ 1λ²κ³Ό 2λ²μ μ΄λ―Έ μμμ λ€λ£¬λ° μλ€. κ·Έλμ μ΄λ²μλ 3λ²μ λν΄νΈ μμ±μκ° μλ κ²½μ°λ₯Ό μ΄ν΄λ³΄μ.
no valid constructor
InvalidClassException μ€ μμ±μκ° μλ€λ μμΈλ ν΄λμ€ μμ κ΄κ³μμμ μ§λ ¬νλ₯Ό ννμμλ λ°μνλ€.
ν΄λμ€ μμ κ΄κ³ ꡬ쑰μμμ μ§λ ¬νλ μμ ν΄λμ€λΆν° μ§λ ¬νν λ€ λΆλͺ¨ ν΄λμ€λ‘ μ΄λν΄μ μ§λ ¬ν νκ² λλ€. κ·Έλ¦¬κ³ κ°μ²΄λ₯Ό μμ§λ ¬νν λ λ°λλ‘ λΆλͺ¨ ν΄λμ€ λΆν° μμν΄μ μμ ꡬ쑰λ₯Ό λ°λΌ λ΄λ €κ°κ² λλ€.
κ·Έλ°λ° λ§μΌ λΆλͺ¨ ν΄λμ€κ° non-serializable(μ§λ ¬νλ₯Ό ꡬννμ§ μμ) νλ€λ©΄ μμ§λ ¬ννλ κ³Όμ μμ μ§λ ¬νλμ§ μμ λΆλͺ¨μ μμ± μ 보λ€μ κΈ°λ³Έ μμ±μλ₯Ό ν΅ν΄μ κ°μ Έμ€κ² λλ€. κ·Έλ°λ° λ§μΌ κΈ°λ³Έ μμ±μκ° μλ€λ©΄ λΆλ¬μ¬ μ ν¨ν μμ±μ(vaild constructor)κ° μμ΄μ μ€λ₯κ° λλ κ²μ΄λ€.
μλ₯Ό λ€μ΄ UserInfoμ λΆλͺ¨ ν΄λμ€μΈ UserAccountκ° name κ³Ό passwordλ₯Ό λ°λ 컀μ€ν μμ±μλ₯Ό μ μνκ² λλ©΄, κΈ°μ‘΄μ κΈ°λ³Έ μμ±μλ μ¬λΌμ§κ² λλ€. μ΄ μνμμ μ§λ ¬ν λ° μμ§λ ¬νλ₯Ό μννκ² λλ©΄ no valid constructor μμΈκ° λ°μλκ² λλ€.
class UserAccount {
String name;
String password;
// ! κΈ°λ³Έ μμ±μ μμΌλ©΄ InvalidClassException : no valid constructor λ°μ
// public UserAccount() {}
UserAccount(String name, String password) {
this.name = name;
this.password = password;
}
}
class UserInfo extends UserAccount implements Serializable {
int age;
int height;
boolean marreid;
UserInfo(String name, String password, int age, int height, boolean marreid) {
super(name, password);
this.age = age;
this.height = height;
this.marreid = marreid;
}
...
}
λ°λΌμ μμ κ΄κ³μμμ μ§λ ¬νλ₯Ό νν λλ non-serializable ν΄λμ€μ λν΄μ λ°λμ κΈ°λ³Έ μμ±μλ₯Ό μΌλΆλ‘ μ μλ₯Ό ν΄μΌ λλ€λ μ μ μμ§ λ§μμΌ λλ€.
NotSerializableException
λν μ£Όμν΄μΌ ν μ¬νμ ν΄λμ€λ Serializableμ ꡬννκ³ μμ§λ§ λ€λ₯Έ ν΄λμ€μ κ°μ²΄λ₯Ό λ©€λ² λ³μλ‘ κ°μ§κ³ μμ κ²½μ°, κ·Έλ¦¬κ³ κ·Έ μ°Έμ‘°νκ³ μλ ν΄λμ€κ° Serializableμ ꡬννμ§ μμμ κ²½μ°μ΄λ€.
μλ₯Όλ€μ΄ μλμ κ°μ΄ Object κ°μ²΄λ₯Ό νλλ‘ μ°Έμ‘°νκ³ μμ κ²½μ°, Objectλ Serializableμ ꡬννμ§ μμκΈ° λλ¬Έμ NotSerializableExceptionμ΄ λ°μνλ©΄μ μ§λ ¬νμ μ€ν¨νκ² λλ€.
class UserInfo implements Serializable {
String name;
int age;
boolean marreid;
Object obj;
}
λ§μΌ Objectκ° Serializableμ ꡬννλ€λ©΄ λͺ¨λ ν΄λμ€κ° μ§λ ¬ν λ μ μμ κ²μ΄κΈ° λλ¬Έμ μ΅κ³ μ‘°μμΈ Objectλ κΈ°λ³Έμ μΌλ‘ μ§λ ¬νλ₯Ό ꡬννκ³ μμ§ μλ€.
λ°λΌμ Serializableλ₯Ό ꡬνν ν΄λμ€ λ΄λΆμ μ§λ ¬ν νμ§μμ λ€λ₯Έ κ°μ²΄λ₯Ό μ°Έμ‘°νκ³ μλ νλκ° μμ κ²½μ° ν΄λΉ ν΄λμ€λ μ§λ ¬νκ° κ°λ₯νλλ‘ Serializable μΈν°νμ΄μ€λ₯Ό ꡬννλλ‘ μ€μ νκ±°λ transient ν€μλλ₯Ό ν΅ν΄ μ§λ ¬ν μ μΈ μ€μ μ ν΄μ£Όμ΄μΌ νλ€.
μΆκ°λ‘ String νμ λ μΌμ’ μ ν΄λμ€μΈλ° μ§λ ¬νκ° κ°λ₯ν μ΄μ λ, String ν΄λμ€ λͺ μΈλ₯Ό 보면 Serializable μΈν°νμ΄μ€λ₯Ό ꡬννκ³ μκΈ° λλ¬Έμ΄λ€.
μλ° μ§λ ¬ν λ¬Έμ μ
μ΄ ννΈλ μλ°(Java) κ°λ°μλΌλ©΄ νλ²μ―€ μ½μ΄λ΄μΌ νλ μ‘°μμ λΈλ‘ν¬(Joshua Bloch)μ μ μ μ΄νν°λΈ μλ° 3/E νμ μ§λ ¬ν λΆλΆμ λ¨ΉκΈ° μ’κ²(κΈ°μ΅νκΈ° μ’κ²) μμ½ κ΅¬μ±ν κΈμ΄λ€. βοΈ
Serializable μΈν°νμ΄μ€λ₯Ό ν΄λμ€μ implements νλ©΄ μμ£Ό κ°λ¨νκ² μ§λ ¬ν κ°λ₯ν ν΄λμ€κ° λμ΄ μΈλΆλ‘ λ΄λ³΄λΌ μ μλ€. κ·Έλ¬λ κ°λ¨ν μ μΈ λ°©λ²κ³Ό λ€λ₯΄κ² μ§λ ¬ν ꡬν λκ°λ λ§€μ° λΉμΈλ€. μ§λ ¬νλ₯Ό ꡬνν μκ°λΆν° λ§μ μνμ±μ κ°κ² λκΈ° λλ¬Έμ΄λ€. μ΄μ λν΄μ μμΈν μμ보λλ‘ νμ.
μλ° μ§λ ¬νμ λμμ μ°ΎμΌλΌ
ν¬μ€ν μ΄λ°μ JSONκ³Όμ λΉκ΅λ₯Ό ν΅ν΄ μ§λ ¬νμ μ₯μ μ λν΄ μκ°λ₯Ό νμμ§λ§, μ¬μ€ μ§λ ¬νλ μ₯μ λ³΄λ€ λ¨μ μ΄ κ·Ήλͺ νκ² λ§λ€.
1. μ§λ ¬νλ μ©λμ΄ ν¬λ€
μ§λ ¬νλ κ°μ²΄μ μ μ₯λ λ°μ΄ν°κ° λΏλ§ μλλΌ νμ μ 보, ν΄λμ€ λ©ν μ 보λ₯Ό κ°μ§κ³ μμΌλ―λ‘ μ©λμ μκ·Όν λ§μ΄ μ°¨μ§νλ€. κ·Έλμ κ°μ μ 보λ₯Ό μ§λ ¬νλ‘ μ μ₯νλλ JSONμΌλ‘ μ μ₯νλλλ νμΌ μ©λ ν¬κΈ°κ° κ±°μ 2λ°° μ΄μ μ°¨μ΄κ° λλ€.
λ°λΌμ DB, Cache λ±μ μΈλΆμ μ μ₯ν λ, μ₯κΈ°κ° λμ μ μ₯νλ μ 보λ μ§λ ¬νλ₯Ό μ§μν΄μΌ λλ€.
2. μμ§λ ¬νλ μννλ€
κ²°λ‘ λΆν° λ§νμλ©΄ μ§λ ¬ν μ€μ μ체λ λ¬Έμ λ μμ§λ§, λ¨μ΄ λ§λ κ²μ μμ§λ ¬ν κ³Όμ μμ λλ λͺ¨λ₯΄κ² 곡격λΉν μνμ±μ΄ μλ€.
μμ§λ ¬ν κ³Όμ μμ νΈμΆλμ΄ μ μ¬μ μΌλ‘ μνν λμμ μννλ λ©μλλ₯Ό κ°μ ―(gadget) μ΄λΌκ³ λΆλ₯΄λλ°, λ°μ΄νΈ μ€νΈλ¦Όμ μμ§λ ¬ννλ ObjectInputStreamμ readObject() λ©μλλ₯Ό νΈμΆνκ² λλ©΄ κ°μ²΄ κ·Έλνκ° μμ§λ ¬νλμ΄ classpath μμ λͺ¨λ νμ
μ κ°μ²΄λ₯Ό λ§λ€μ΄ λ΄κ² λλλ°, ν΄λΉ νμ
κ°μ²΄μμ λͺ¨λ μ½λλ₯Ό μνν μ μκ² λλ―λ‘ λμ νλ‘κ·Έλ¨ μ½λ μ μ²΄κ° κ³΅κ²© λ²μμ λ€μ΄κ°κ² λλ€.
λλ κ°μ²΄λ₯Ό μ§λ ¬ννμ¬ μΈλΆλ‘ μ μ‘νλ κ³Όμ μμ μ€κ°μ λκ° κ°λ‘μ± νμΌ λ°μ΄νΈ λ΄μ©μ μ‘°μνμ¬, μ‘μ μκ° μμ§λ ¬ννλ κ³Όμ μμ μΈμ€ν΄μ€μ μνν κ°μ λμ μμΌ λΆλ³μ κΉ¨λ μμΌλ‘μ 곡격λ κ°λ₯νλ€. μλνλ©΄ μμ§λ ¬νλ μμ±μ μμ΄ μΈμ€ν΄μ€νκ° κ°λ₯νκΈ° λλ¬Έμ 보μ΄μ§ μλ μμ±μ λΌκ³ λ λΆλ¦¬μ΄λ€.
λ°λΌμ μ λ’°ν μ μλ λ°μ΄ν°λ μ λ μμ§λ ¬ν νλ©΄ μλλ©°, μ§λ ¬νμ μ μ¬μ μΈ μνμ±μ ννΌνλ κ°μ₯ μ’μ λ°©λ²μ μ무κ²λ μμ§λ ¬ννμ§ μλ κ²μ΄λ€.
3. μ§λ ¬νλ₯Ό λ체 ν μ μλ€λ©΄
λ§μΌ Serializableμ ꡬνν ν΄λμ€λ§ μ§μνλ νλ μμν¬λ₯Ό μ¬μ©ν΄μΌ νκ±°λ λ κ±°μ μμ€ν λλ¬Έμ μ΄μ©μ μμ΄ ν΄λμ€μ μ§λ ¬νλ₯Ό μ€μ ν΄μΌ ν κ²½μ°, μ§λ ¬νλ₯Ό νΌν μ μλ€λ©΄ μμ§λ ¬ν νν°λ§(ObjectInputFilter)κ³Ό κ°μ μμ§λ ¬ν λ°©μ΄ κΈ°λ²λ€μ μ¬μ©νλ©΄ λλ€. λ°μ΄ν° μ€νΈλ¦Όμ΄ μμ§λ ¬νλκΈ° μ μ νν° μ‘°κ±΄λ¬Έμ μννμ¬ νΉμ ν΄λμ€λ§ νμ©νκ±°λ μ μΈνλλ‘ ν μ μλ€.
κ·Έλ¬λ κ΄λ ¨λ λͺ¨λ² μ¬λ‘λ₯Ό λ°λΌμ μ§λ ¬ν κ°λ₯ ν΄λμ€λ€μ 곡격μ λλΉνλλ‘ μμ±νλ€ ν΄λ μ¬μ ν μ·¨μ½νκΈ° λλ¬Έμ κ°μ₯ νμ€ν λ°©λ²μ μμ§λ ¬νλ₯Ό μνλ κ²μ΄λ€.
μ§λ ¬νλ₯Ό ꡬνν μ§λ μ μ€ν κ²°μ νλΌ
1. λ¦΄λ¦¬μ¦ νμ μμ μ΄ μ΄λ ΅λ€
ν΄λμ€κ° Serializableμ ꡬννκ² λλ©΄ μ§λ ¬νλ λ°μ΄νΈ μ€νΈλ¦Ό μΈμ½λ©λ νλμ κ³΅κ° APIκ° λλ κ²μ΄λ€. κ·Έλμ μ§λ ¬νμ ꡬνν ν΄λμ€κ° λ리 νΌμ§λ©΄ κ·Έ μ§λ ¬ν ννλ μμν μ§μν΄μΌνλ€. ν΄λμ€μ λ΄λΆ ꡬνμ μμ νλ€λ©΄ μλμ μ§λ ¬ν ννμ λ¬λΌμ§κ² λκΈ° λλ¬Έμ΄λ€.
μ¦, Serializableμ ꡬνν μκ°λΆν° ν΄λΉ κ°μ²΄μ μ μ§λ³΄μλ μ§λ ¬νμ λ¬Άμ΄κ² λλ κ²μ΄λ€.
2. ν΄λμ€ μΊ‘μνκ° κΉ¨μ§λ€
λ§μΌ μ§λ ¬νν ν΄λμ€μ private λ©€λ²κ° μμ΄λ μ§λ ¬νλ₯Ό νκ² λλ©΄ κ·Έλλ‘ μΈλΆλ‘ λ ΈμΆλκ² λλ€. (μ§λ ¬νλ₯Ό μ μΈνλ €λ©΄ λ³λλ‘ transient μ€μ ν΄μΌ λλ€)
λ°λΌμ Serializableμ ꡬννλ©΄ μ§λ ¬ν ννκ° νλμ κ³΅κ° APIκ° λμ΄ μΊ‘μνκ° κΉ¨μ§κ² λλ€.
3. λ²κ·Έμ 보μμ μ·¨μ½νλ€
μλ°μμλ κ°μ²΄λ₯Ό μμ±μλ₯Ό μ΄μ©ν΄ λ§λ λ κ²μ΄ κΈ°λ³Έμ΄λ€. νμ§λ§ μμ§λ ¬νλ μΈμ΄μ κΈ°λ³Έ λ©μ»€λμ¦μ μ°ννμ¬ κ°μ²΄λ₯Ό λ°λ‘ μμ±νλλ‘ νλ€. μ¦, μμ§λ ¬νλ μ¨μ μμ±μ μ΄κΈ°λ ν κ²μ΄λ€.
λ¬Έμ λ λ§μΌ μ΄λ κ°μ²΄κ° μμ±μλ₯Ό ν΅ν΄ μΈμ€ν΄μ€ν ν λ λΆλ³μμ΄λ νκ°λμ§ μμ μ κ·Όμ μ€μ νμμ κ²½μ° μ΄λ₯Ό 무μνκ³ μμ±λλ€λ μ μ΄λ€.
μλ₯Όλ€μ΄ μλ Member ν΄λμ€λ μμ±μ μ λ ₯κ°μΌλ‘ μ΄μν κ°μ λ£μ κ²½μ° μ΄λ₯Ό κ±Έλ¬λ΄λ λ‘μ§μ΄ μλλ°, Member κ°μ²΄λ₯Ό μ§λ ¬ννκ³ μμ§λ ¬νν κ²½μ° ageμ μμκ°μ΄ λ€μ΄κ°λ μ΄λ₯Ό κ±Έλ¬λΌμ μλ κ²μ΄λ€. (μ΄ λΆλΆμ μμμ μκ°ν μμ§λ ¬ν λ°©μ΄ κΈ°λ² μ€ νλμΈ μ§λ ¬ν νλ‘μ ν¨ν΄μΌλ‘ 극볡μ ν μ μλ€)
class Member implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Member(String name, int age) {
if(age < 0){
throw new IllegalArgumentException();
}
this.name = name;
this.age = age;
}
}
4. μλ‘μ΄ λ²μ μ 릴리μ¦ν λ ν μ€νΈ μμκ° λ§μμ§λ€
λ§μΌ μ§λ ¬ν κ°λ₯ν ν΄λμ€κ° μ λ°μ΄νΈλλ©΄, ꡬλ²μ μ μ§λ ¬ν ννκ° μ λ²μ μμ μμ§λ ¬νκ° κ°λ₯νμ§ ν μ€νΈν΄μΌ ν κ²μ΄λ€. μ¦, ν μ€νΈμ μμ΄ μ§λ ¬ν κ°λ₯ ν΄λμ€μ μμ λ¦΄λ¦¬μ¦ νμμ λΉλ‘νκ² λλ€.
5. ꡬν μ¬λΆλ μ½κ² κ²°μ ν κ²μ΄ μλλ€
Serializableμ κΌ κ΅¬νν΄μΌ νλ€λ©΄ ν΄λμ€λ₯Ό μ€κ³ν λλ§λ€ λ°λ₯΄λ μ΄λκ³Ό λΉμ©μ μ κ³ λ €ν΄μΌ νλ€.
μλ₯Ό λ€μ΄ BigIntegerμ Instant κ°μ 'κ°' ν΄λμ€μ 컬λ μ ν΄λμ€λ Serializableμ ꡬννμκ³ μ€λ λ νμ²λΌ 'λμ' νλ κ°μ²΄λ₯Ό ννν ν΄λμ€λ λλΆλΆ ꡬννμ§ μμλ€.
6. μμμ© ν΄λμ€μ μΈν°νμ΄μ€μ μ§λ ¬ν ꡬνμ μ£Όμν΄μΌ νλ€
μμ λͺ©μ μΌλ‘ μ€κ³λ ν΄λμ€μ μΈν°νμ΄μ€λ₯Ό Serializableμ ꡬννλ€λ κ²μ, μμμ μΈκΈν μλ° μ§λ ¬νμ μνμ±μ κ³ λ₯΄λν νμ ν΄λμ€μκ² μ μ΄νκ² λλ κ²κ³Ό λ€λ¦ μκΈ° λλ¬Έμ΄λ€.
κ·Έλ μ§λ§ λ§μΌ ν΄λμ€κ° μ§λ ¬ν λ° νμ₯μ΄ λͺ¨λ κ°λ₯νλ€κ² νκ³ μΆλ€λ©΄ λͺ κ°μ§ μ£Όμμ¬νμ΄ μλ€.
μΈμ€ν΄μ€ νλμ κ° μ€μ λΆλ³μμ 보μ₯ν΄μΌν κ² μλ€λ©΄ λ°λμ νμ ν΄λμ€μμ Object ν΄λμ€μ finalize λ©μλλ₯Ό μ¬μ μνμ§ λͺ»νκ² ν΄μΌνλ€. finalizeλ₯Ό μ¬μ μνλ©΄μ final ν€μλλ₯Ό λΆμ¬μ μ μΈνλ©΄ λλ€.
κ·Έλ¦¬κ³ μΈμ€ν΄μ€ νλμ€ κΈ°λ³Έκ° intλ 0, Objectλ null λ±μΌλ‘ μ€μ λλ©΄ μλ°°λλ λΆλ³μμ΄ μλ€λ©΄ readObjectNoData λ©μλλ₯Ό λ°λμ μΆκ°ν΄μΌνλ€.
7. λ΄λΆ ν΄λμ€λ μ§λ ¬νλ₯Ό ꡬννλ©΄ μλλ€
λ΄λΆ ν΄λμ€(inner class)μ μ§λ ¬ν ννλ λΆλΆλͺ νλ―λ‘ Serializableμ ꡬννλ©΄ μλλ€.
λ¨ μ μ λ΄λΆ ν΄λμ€(static inner class)λ Serializable μ ꡬνν΄λ μκ΄μλ€.
μ΄μ²λΌ μ§λ ¬νλ λ§μ λ¨μ κ³Ό μν μμκ° μ‘΄μ¬νλ€.
κ·Έλ¬λ μ§λ ¬νλ 1997λ μ νμνμ¬ μ¬μ ν μλ° μνκ³ κ³³κ³³μ μ°μ΄κ³ μλ€. κ·Έλμ λ§μΌ μ΄μ©μ μμ΄ Serializableλ₯Ό ꡬνν΄μΌ νλ€λΌλ©΄, κ·Έμ λ°λ₯Έ λΉμ©μ΄ μ μ§ μμΌλ ν΄λμ€λ₯Ό μ€κ³ ν λλ§λ€ μ΄λκ³Ό λΉμ©μ μ μ μΈμ§ν΄μΌ νλ€. νμ§λ§ μκ°κ³Ό λ Έλ ₯μ λ€μ¬μλΌλ JSON λ±μΌλ‘ λ°μ΄ν° ννμΌλ‘ λ§μ΄κ·Έλ μ΄μ νλ κ²μ μΆμ²νλ λ°μ΄λ€.
# μ°Έκ³ μλ£
μ΄νν°λΈ μλ° Effective Java 3/E
https://techblog.woowahan.com/2550/
https://www.benchresources.net/serialization-and-de-serialization-in-java/
https://www.studytonight.com/java-examples/java-serialization-and-deserialization
https://youtu.be/3iypR-1Glm0
https://www.scaler.com/topics/transient-keyword-in-java/