β μλ° μμ§λ ¬ν λ°©μ΄ κΈ°λ² - μ΄μ 리 λͺ¨μ
Serializable ꡬνμ 보μμ ꡬλ©μ΄ μκΈΈ μ μλ€
λ³΄ν΅ μλ°μμ μΈμ€ν΄μ€λ μμ±μλ₯Ό μ΄μ©ν΄ λ§λ λ κ²μ΄ κΈ°λ³Έμ΄λ€. νμ§λ§ μμ§λ ¬νλ μΈμ΄μ κΈ°λ³Έ λ©μ»€λμ¦μ μ°ννμ¬ κ°μ²΄λ₯Ό λ°λ‘ μμ±νλλ‘ νλ€. μ§λ ¬νλ νμΌμ΄λ λ°μ΄ν°λ§ μλ€λ©΄ readObject() λ₯Ό ν΅ν΄ μμ±μ μμ΄ κ³§λ°λ‘ μΈμ€ν΄μ€λ₯Ό λ§λ€μ μκΈ° λλ¬Έμ΄λ€.
μ¦, μμ§λ ¬νλ 보μ΄μ§ μμ μμ±μ μ΄κΈ°λ ν κ²μ΄λ€. λ¬Έμ λ λ§μΌ μ΄λ κ°μ²΄κ° μμ±μλ₯Ό ν΅ν΄ μΈμ€ν΄μ€ν ν λ λΆλ³μμ΄λ νκ°λμ§ μμ μ κ·Όμ μ€μ νμμ κ²½μ° μ΄λ₯Ό 무μνκ³ μμ±λλ€λ μ μ΄λ€.
μλ₯Όλ€μ΄ μλ Member ν΄λμ€λ μμ±μλ‘ λμ΄ μ λ ₯κ°μ μμλ₯Ό λ£μΌλ©΄ μ΄λ₯Ό κ±Έλ¬λ΄λ λ‘μ§μ΄ μλ€κ³ νλ€.
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;
}
@Override
public String toString() {
return "Member{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
μλ 첨λΆνμΌμ μμ μ λκ΅°κ°κ° Member κ°μ²΄λ₯Ό μ§λ ¬ννμ¬ μ μ₯ν νμΌμ΄λΌκ³ νλ€. κ·Έλ°λ° λκ΅°κ° μ΄λ₯Ό κ°λ‘μ±μ΄ λͺ°λ κ°μ μ‘°μνλ€.
μ°λ¦¬ νμ κ·Έ μ¬μ€μ λͺ¨λ₯΄κ³ μ΄λ₯Ό μμ§λ ¬ν νμ¬ νλ‘κ·Έλ¨μ μ€ννμλ€.
public static void main(String[] args) throws IOException, ClassNotFoundException {
// μμ§λ ¬ν
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream("Student.ser")));
Member member = (Member) in.readObject();
in.close();
System.out.println(member);
}
μ΄μ²λΌ -100 μ΄λΌλ μ³μ§ μλ κ°μΌλ‘ μ‘°μλμ΄λ, readObject() λ‘ μμ§λ ¬ν νλ κ³Όμ μ ν΅ν κ°μ²΄ μμ±μ λΆλ³μμ 무μνκ³ μ΄μν κ°μ΄ λ€μ΄κ°κ² λλ€.
λ§μ½ μ΄κ² λκ³Ό κ΄λ ¨λ κ°μ΄λΌλ©΄ ν΄μ»€μ μ‘°μμ μν΄ μμ²λκ² ν°μΌ λ μ μλ μνν μν©μ΄κ² λλ€.
컀μ€ν μ§λ ¬ν λ°©μ΄ κΈ°λ²
μ΄λ₯Ό λ°©μ΄νλ κ°μ₯ κ°λ¨ν κΈ°λ²μ readObject λ©μλλ₯Ό μ§λ ¬ν ꡬν체 ν΄λμ€μ μ¬μ μνμ¬ μ ν¨μ± κ²μ¬ λ‘μ§μ μ보λ κ²μ΄λ€. κ·Έλ¬λ©΄ μμ§λ ¬νμ readObject() κ° νΈμΆλλ©΄, μ§λ ¬ν ν΄λμ€μ readObject λ©μλκ° λμ μ€νλκ² λλ€.
μ΄μ²λΌ κΈ°λ³Έ μ§λ ¬ν λμμ 컀μ€ν νλ€λ μ μμ 컀μ€ν μ§λ ¬ν λΌκ³ λΆλ¦¬μ΄λ€.
class Member implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Member(String name, int age) {
this.name = name;
checkPositive();
this.age = age;
}
private void checkPositive() {
if (this.age < 0) {
throw new RuntimeException(new InvalidObjectException("age κ°μ΄ μ³μ§ μμ΅λλ€."));
}
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject(); // κΈ°λ³Έ μμ§λ ¬ν λ‘μ§ μ€ν
checkPositive();
}
@Override
public String toString() {
return "Member{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
λ€μ μμ§λ ¬νλ₯Ό μννλ©΄ κ·Έλλ‘ checkPositive() λ©μλμ μ ν¨μ± κ²μ¬ λ‘μ§μ κ±Έλ € μμΈλ₯Ό λ°μλλ κ²μ νμΈ ν μ μλ€.
μ 리νμλ©΄ μμ§λ ¬νν λ μ€κ°μ μ΄λ ν κ³΅κ²©μ΄ μμμ§ λͺ¨λ₯΄κΈ° λλ¬Έμ κ°μ Έμ¨ λ°μ΄νΈ μ€νΈλ¦Όμ΄ μ§μ§ μ§λ ¬νλ λ°μ΄ν°λΌκ³ λ―ΏμΌλ©΄ μλλ©°, μ΄λ€ λ°μ΄νΈ μ€νΈλ¦Όμ΄ λμ΄μ€λλΌλ μ ν¨μ± κ²μ¬ λ±μ λ‘μ§μ ν΅ν΄ μ ν¨ν μΈμ€ν΄μ€λ₯Ό λ§λ€μ΄ λ΄μΌ λλ€λ μ μ΄λ€. λ§μΌ μ΄κΈλλ€λ©΄ κ³Όκ°νκ² InvalidObjectException μ λμ§λ€.
νμ§λ§ μ΄λ¬ν ννλ λμ€μ μ μ§λ³΄μ μΈ‘λ©΄μμ κ°μ μΌλ‘ μμ©νλ€. μλνλ©΄ κ°μ μ ν¨μ± κ²μ¬ λ‘μ§μ μ€λ³΅ν΄μ μμ±ν΄μΌ νκΈ° λλ¬Έμ νλ μ½λ©ν λκΈ° λλ¬Έμ΄λ€. κ·Έλμ λμ€μ κ°λ°μκ° μ€μλ₯Ό ν μ μλ€λ λ¬Έμ μ μ΄ λνλλ€.
λ¬Όλ‘ μ§κΈμ μμ£Ό κ°λ¨ν λ‘μ§μ΄λΌ λ¬Έμ μκΈΈ μΌμ μκ² μ§λ§ μ¬λ¬κ°μ 볡μ‘ν λ‘μ§μΌ κ²½μ° λͺ¨λ₯΄κ² λλ€.
λ°λΌμ μμ§λ ¬ν λ°©μ΄ κΈ°λ²μ κ°μ₯ μΆμ²λλ κ²μ μ§λ ¬ν νλ‘μ ν¨ν΄μ μ΄μ©νλ κ²μ΄λ€. λμμΈ ν¨ν΄μ νλ‘μ ν¨ν΄μ λ³ν ν¨ν΄μ΄λ©° νλ² μ λλ‘ μ€μ λ§ ν΄μ£Όλ©΄ μμ§λ ¬νλ₯Ό μμ νκ² λ§λλ λ° νμν λ Έλ ₯μ μ€μ¬μ€λ€.
μ§λ ¬ν νλ‘μ ν¨ν΄
μ§λ ¬ν νλ‘μ ν¨ν΄(Serialization Proxy Pattern)μ μ§λ ¬νλ₯Ό μλ³Έμ΄ μλ νλ‘μ κ°μ²΄κ° λμ μ§λ ¬νλκ³ , μμ§λ ¬νν λ νλ‘μμμ μλ³Έ κ°μ²΄λ₯Ό λ°ννμ¬ μΈμ€ν΄μ€ν νλ κΈ°λ²μ΄λ€.
μ§λ ¬ν νλ‘μλ₯Ό ꡬμ±νλ κ³Όμ μ λ€μκ³Ό κ°λ€.
- νλ‘μ ν΄λμ€ MemberProxyλ₯Ό λμ Member ν΄λμ€μ μ μ λ΄λΆ ν΄λμ€(static inner class)λ‘ μ μΈνλ€.
- Member ν΄λμ€μ
writeReplace()λ©μλλ₯Ό μ μνμ¬, Memberλ₯Ό μ§λ ¬νμ νλ‘μ κ°μ²΄λ₯Ό λ°ννμ¬ MemberProxyκ° μ§λ ¬ν λλλ‘ μ μ΄νλ€. - κ·Έλ¦¬κ³ Member ν΄λμ€μ
readObject()λ©μλλ₯Ό μ μνμ¬ μ§μ μ§λ ¬νλ₯Ό νμ§ λͺ»νλλ‘ μλ¬λ₯Ό λμ§λλ‘ νλ€. νλ‘μκ° λμ μ§λ ¬νλλ μλ³Έμ΄ μ§λ ¬ν λ μΌμ΄ μκΈ° λλ¬Έμ΄λ€. - λ§μ§λ§μΌλ‘ MemberProxy ν΄λμ€ λ΄μ
readResolve()λ©μλλ₯Ό μ μνμ¬, νλ‘μλ₯Ό μμ§λ ¬νν μ νλ‘μ κ°μ²΄κ° μλ μλ³Έ Member κ°μ²΄λ₯Ό λ°ννλλ‘ μ μ΄νλ€.
writeReplace()λ μ§λ ¬νμ κ°μνλ λ©μλλΌ λ³΄λ©΄λκ³ ,readResolve()λ μμ§λ ¬νμ κ°μνλ λ©μλλΌ λ³΄λ©΄ λλ€.
class Member implements Serializable {
private static final long serialVersionUID = 1L;
private final String name;
private final int age;
public Member(String name, int age) {
this.name = name;
checkPositive();
this.age = age;
}
private void checkPositive() {
if (this.age < 0) {
throw new RuntimeException(new InvalidObjectException("age κ°μ΄ μ³μ§ μμ΅λλ€."));
}
}
// μ§λ ¬ν νλ‘μ (μ μ λ΄λΆ ν΄λμ€)
private static class MemberProxy implements Serializable {
private static final long serialVersionUID = 2L;
private final String name;
private final int age;
// μμ±μλ λ¨ νλμ¬μΌ νκ³ , λ°κΉ₯ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό 맀κ°λ³μλ‘ λ°κ³ λ°μ΄ν°λ₯Ό 볡μ¬
public MemberProxy(Member m) {
this.name = m.name;
this.age = m.age;
}
// κ°μ²΄λ₯Ό μμ§λ ¬ν ν λ νΈμΆλμ΄, μμ§λ ¬ν κ²°κ³Όλ₯Ό readResolve λ°νκ°μΌλ‘ μ€μ
private Object readResolve() {
return new Member(name, age); // μμ§λ ¬νλλ©΄ μ΅μ’
μ μΌλ‘ Member κ°μ²΄λ₯Ό λ°ν
}
}
// κ°μ²΄λ₯Ό μ§λ ¬ν ν λ νΈμΆλμ΄, μ§λ ¬ν λμμ writeReplaceλ₯Ό ν΅ν΄ νλ‘μλ₯Ό λ°ννλλ‘ μ μ΄
private Object writeReplace() {
return new MemberProxy(this); // νλ‘μκ° λμ μ§λ ¬ν
}
// λμ κ°μ²΄(Member)μ μμ§λ ¬ν νμ§ λͺ»νκ² λ§λλ€.
// μ μ΄μ νλ‘μ κ°μ²΄λ‘ μ§λ ¬ννκ³ μμ§λ ¬ννκΈ° λλ¬Έμ λμ κ°μ²΄κ° μμ§λ ¬ν λ μΌμ΄ μκΈ° λλ¬Έμ΄λ€
private void readObject(ObjectInputStream ois) throws InvalidObjectException {
throw new InvalidObjectException("νλ‘μκ° νμν΄μ.");
}
@Override
public String toString() {
return "Member{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
μ§λ ¬ν νλ‘μ κ³Όμ
1. Member μΈμ€ν΄μ€λ₯Ό λ§λ€κ³ μ§λ ¬νλ₯Ό μννλ€.
Member student1 = new Member("νκΈΈλ", 22);
// μ§λ ¬ν
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("Student.ser")));
out.writeObject(student1);
out.close();
2. writeObject κ° νΈμΆλλ©΄ writeReplace κ° νΈμΆλλλ°, μ΄λ MemberProxyλ₯Ό λ°ννμ¬ νλ‘μ κ°μ²΄κ° μ§λ ¬ν λκ² λλ€. κ·Έλ¦¬κ³ νλ‘μλ Memberμ λ©€λ²κ°μ κ·Έλλ‘ κ³μΉνμ¬ κ°μ§κ³ μκ² λλ€.
3. μμ§λ ¬νλ₯Ό μννλ€. μ΄λ μ§λ ¬ν νμΌμλ νλ‘μ κ°μ²΄κ° λ°μ΄νΈ μ€νΈλ¦ΌμΌλ‘ λ€μ΄ μλ€.
// μμ§λ ¬ν
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream("Student.ser")));
Member member = (Member) in.readObject();
in.close();
System.out.println(member);
4. readObject κ° νΈμΆλλ©΄ νλ‘μ κ°μ²΄κ° μμ±λκ² λλ©΄μ, MemberProxy λ΄μ readResolve κ° νΈμΆλμ΄ Member κ°μ²΄λ₯Ό λ°ννλλ‘ νλ€. μ΄λ Member μμ±μμμ μμ§λ ¬νν λ°μ΄ν°μ λν μ ν¨μ± κ²μ¦μ νκ² λλ€.
5. μ΅μ’ μ μΌλ‘ νλ‘μλ₯Ό ν΅ν΄ κ²μ¦μ΄ μλ£λ Member μΈμ€ν΄μ€λ₯Ό μ»κ² λλ€.
6. μ 체 κ³Όμ μ λμ΄ν΄λ³΄λ©΄ μλμ κ°μ΄ ννν μ μλ€.
μ§λ ¬ν νλ‘μ ν¨ν΄ μ₯λ¨μ
μ§λ ¬ν νλ‘μ μ₯μ
- κ°μ§ λ°μ΄νΈ μ€νΈλ¦Ό 곡격과 λ΄λΆ νλ νμ·¨ 곡격μ νλ‘μ μμ€μμ μ°¨λ¨ν΄μ€λ€
- νλλ€μ finalλ‘ μ μΈν΄λ λμ΄μ λμ ν΄λμ€λ₯Ό μ§μ ν λΆλ³μΌλ‘ λ§λ€μ΄ μ€λ€.
- μμ§λ ¬νλ readObject μ¬μ μλ‘ μΌμΌν μ ν¨μ± κ²μ¬λ₯Ό νμ§ μμλ λλ€.
- μμ§λ ¬νν μΈμ€ν΄μ€μ μλμ μ§λ ¬νλ μΈμ€ν΄μ€μ ν΄λμ€κ° λ¬λΌλ μ μ μλνλ€.
- μ§λ ¬ν νλ‘μλ readObject μ λ°©μ΄μ 볡μ¬λ³΄λ€ κ°λ ₯νλ€.
μ§λ ¬ν νλ‘μ νκ³
- μ§λ ¬ν & μμ§λ ¬ν κ³Όμ μ΄ μλμ μΌλ‘ λ리λ€
- ν΄λΌμ΄μΈνΈκ° λ§μλλ‘ νμ₯ν μ μλ ν΄λμ€μλ μ μ©ν μ μλ€.
- ν΄λμ€μ νλ κ°μ²΄κ° μλ‘ μ°Έμ‘°νλ μν©, κ°μ²΄ κ·Έλνμ μνμ΄ μλ ν΄λμ€μλ μ μ©ν μ μλ€.
μμ§λ ¬ν νν°λ§
λ§μΌ Serializableμ ꡬνν ν΄λμ€λ§ μ§μνλ νλ μμν¬λ₯Ό μ¬μ©ν΄μΌ νκ±°λ λ κ±°μ μμ€ν λλ¬Έμ μ΄μ©μ μμ΄ ν΄λμ€μ μ§λ ¬νλ₯Ό μ€μ ν΄μΌ ν κ²½μ°, κ·Έλ°λ° μμ§λ ¬νν λ°μ΄ν°κ° μμ νμ§ νμ ν μ μμ κ²½μ°, κ°μ²΄ μμ§λ ¬ν νν°λ§ (Deserialization Filters) μ ν΅ν΄ μμ§λ ¬νν μΈμ€ν΄μ€λ₯Ό νν°λ§νμ¬ λ°©μ΄ν μ μλ€.
μμ§λ ¬ν νν°λ§μ λ°μ΄ν° μ€νΈλ¦Όμ΄ μμ§λ ¬νλκΈ° μ μ νν° μ‘°κ±΄λ¬Έμ μννμ¬ νΉμ ν΄λμ€λ§ μμ§λ ¬μ νμ©νκ±°λ μμ μ μΈνμ¬ μμ§λ ¬μ λͺ»νλλ‘ μμ λΌ μ μλ€.
μμ§λ ¬ν νν°λ§ ν΄λμ€μΈ java.io.ObjectInputFilter λ JDK 9 λ²μ μμ μ¬μ©ν μ μλ€.
ObjectInputFilterλ ν¨μν μΈν°νμ΄μ€μ΄λ€.
λλ€μμ ν΅ν΄ μμ§λ ¬ννλ κ°μ²΄μ ν΄λμ€λͺ
μ λΉκ΅ν΄μ ObjectInputFilter.Status.ALLOWED μ ObjectInputFilter.Status.REJECTED λ₯Ό κ°κ° λ°ννλλ‘ μ€μ νλ μΌκΈ ν¨μλ₯Ό λ§λ€κ³ , setObjectInputFilter() λ₯Ό ν΅ν΄ νν°λ₯Ό ObjectInputFilter κ°μ²΄μ λ±λ‘νλ€. κ·Έλ¦¬κ³ μμ§λ ¬νλ₯Ό μννλ©΄ λΈλ리μ€νΈμ κ±Έλ¦° ν΄λμ€λ μμΈκ° λ°μλκ² λλ€.
// μμ§λ ¬νκ° νμ©λλ ν΄λμ€
class SuccessDeserializer implements Serializable {
}
// μμ§λ ¬νκ° λΉ νμ© λλ ν΄λμ€
class NegativeDeserializer implements Serializable {
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
SuccessDeserializer successObj = new SuccessDeserializer();
NegativeDeserializer nagativeObj = new NegativeDeserializer();
String filename = "filter.ser";
// μ§λ ¬ν -------------------
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(filename)));
out.writeObject(successObj);
out.writeObject(nagativeObj);
out.close();
// μμ§λ ¬ν -------------------
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(filename)));
// 1. μμ§λ ¬ν νν° λ§λ€κΈ°
ObjectInputFilter filter = (filterInfo) -> {
Class<?> classObj = filterInfo.serialClass();
// νμ΄νΈ 리μ€νΈ
if (classObj.getName().equals("SuccessDeserializer")) {
return ObjectInputFilter.Status.ALLOWED; // SuccessDeserializer ν΄λμ€μΌ κ²½μ° νμ©
}
System.out.println("Rejected :" + classObj.getSimpleName());
return ObjectInputFilter.Status.REJECTED; // κ·Έ μ΄μΈμλ κ±°μ
};
// 2. μμ§λ ¬ν νν° λ±λ‘
in.setObjectInputFilter(filter);
// 3. νν° μ μ©λ μ±λ‘ μμ§λ ¬ν
Object obj1 = in.readObject();
Object obj2 = in.readObject();
System.out.println("Class Name: " + obj1.getClass().getSimpleName());
System.out.println("Class Name: " + obj2.getClass().getSimpleName());
in.close();
}
μμ§λ ¬ν νν°λ§ λΆκΈ° λ‘μ§μ ꡬμ±ν λ, λΈλ리μ€νΈ λ°©μ보λ€λ νμ΄νΈλ¦¬μ€νΈ λ°©μμ μΆμ²νλ€. λΈλ리μ€νΈ λ°©μμ μ΄λ―Έ μλ €μ§ μνμΌλ‘λΆν°λ§ 보νΈν μ μκΈ° λλ¬Έμ΄λ€.
λν μ ν리μΌμ΄μ μ μν νμ΄νΈλ¦¬μ€νΈλ₯Ό μλμΌλ‘ μμ±ν΄μ£Όλ μ€μ(SWAT) μ΄λΌλ λꡬλ₯Ό μ΄μ©ν μλ μλ€.
κ°μ²΄ μμ μ§λ ¬ν λ°©μ΄ κΈ°λ²
Serializableλ₯Ό ꡬνν ν΄λμ€λ μμ μ μμν μμ κ°μ²΄λ€ κΉμ§ μ§λ ¬νκ° κ°λ₯νκ² λλ―λ‘, μ§λ ¬νμ λ¬Έμ λ₯Ό κ³ μ€λν μ νλκΈ° λλ¬Έμ μμμ©μΌλ‘ μ€κ³λ ν΄λμ€λ Serializableμ ꡬννλ©΄ μλλ©°, μΈν°νμ΄μ€λ Serializableμ νμ₯νλ©΄ μλλ€.
κ·Έλ¬λ νκ²½μ μΈ μμΈμΌλ‘ μ΄μ©μ μμ΄ ν΄λμ€μ μΈμ€ν΄μ€ νλκ° μ§λ ¬νμ νμ₯μ΄ λͺ¨λ κ°λ₯νκ² κ΅¬νν΄μΌ νλ€λ©΄ λͺκ°μ§ μ£Όμμ μ΄ μλ€.
첫λ²μ§Έλ, μΈμ€ν΄μ€ νλμ κ° μ€μ λΆλ³μμ 보μ₯ν΄μΌν κ² μλ€λ©΄ λ°λμ νμ ν΄λμ€μμ Object μ΅μμ ν΄λμ€μ finalize() λ©μλλ₯Ό μ¬μ μνμ§ λͺ»νκ² ν΄μΌνλ€. λ°©λ²μ finalizeλ₯Ό μ€λ²λΌμ΄λ© νλ©΄μ final ν€μλλ₯Ό λ©μλμ λΆμ΄λ©΄ λλ€. μ΄λ κ² νμ§ μμΌλ©΄ finalizer 곡격μ μ·¨μ½ν΄μ§ μ μλ€.
λλ²μ§Έλ, μΈμ€ν΄μ€ νλμ€ κΈ°λ³Έκ° intλ 0, Objectλ null λ± μΌλ‘ μ€μ λλ©΄ μλ°°λλ λΆλ³μμ΄ μλ€λ©΄ readObjectNoData() λ©μλλ₯Ό λ°λμ μΆκ°ν΄μΌνλ€. readObjectNoData() λ Java 4 λ²μ λΆν° μ§μνλ λ©μλλ‘ κΈ°μ‘΄ μ§λ ¬ν κ°λ₯ ν΄λμ€μ μ§λ ¬ν κ°λ₯ μμ ν΄λμ€λ₯Ό μμνλ λλ¬Έ κ²½μ°λ₯Ό μν λ©μλμ΄λ€. μ΄μ λν΄μ μμΈν μμ보μ.
readObjectNoData μ¬μ©λ²
readObjectNoData λ₯Ό μ¬μ©νλ μν©μ, κΈ°μ‘΄μ μ§λ ¬ν κ°λ₯ν A, B λ ν΄λμ€κ° μλλ°, κ°μκΈ° Bκ° Aλ₯Ό μμνλ μν©μ΄ λ°μν λ μΌμ΄λλ λ°μ΄ν° λΆμΌμΉ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄μμ΄λ€.
μλ₯Ό λ€μ΄ Serializableλ₯Ό ꡬννλ Person ν΄λμ€μ Student ν΄λμ€κ° μλ€κ³ νμ. κ·Έμ€ Student μΈμ€ν΄μ€λ§ μ§λ ¬ννμ¬ μΈλΆ νμΌλ‘ μ μ₯νλ€κ³ νλ€.
class Person implements Serializable {
private static final long serialVersionUID = 1L;
String name;
long age;
public Person() {
}
public Person(String name, long age) {
this.name = name;
this.age = age;
}
}
class Student implements Serializable {
private static final long serialVersionUID = 2L;
String school;
String circles;
public Student(String school, String circles) {
this.school = school;
this.circles = circles;
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Student student1 = new Student("μΈμ’
λνκ΅", "κ²μλμ리");
// μ§λ ¬ν
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("Student.ser")));
out.writeObject(student1);
out.close();
// μμ§λ ¬ν
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream("Student.ser")));
Student student2 = (Student) in.readObject();
in.close();
System.out.println(student2.school);
System.out.println(student2.circles);
}
κ·Έλ¬λ©΄ Student.ser νμΌμ λ΄κ²¨μλ μ§λ ¬νν μ 보λ Studentμ company νλμ team νλλ§ κ°μ§κ³ μκ² λλ€.
κ·Έλ°λ° κ°μκΈ° λͺ
μΈμκ° λ°λμ΄μ Student ν΄λμ€κ° Person ν΄λμ€λ₯Ό μμνλ€κ³ νλ€. κ·Έλ¬λ©΄ Student ν΄λμ€κ° κ°μ©νλ νλλ€μ name, age, school, circles μ΄ 4κ°κ° λκ² λλ€.
Personμ Serializableμ ꡬννκ³ μκΈ° λλ¬Έμ Studentμμλ μΈν°νμ΄μ€λ₯Ό ꡬνν νμκ° μμΌλ μ½λμμ μ κ±°ν΄μ€λ€.
class Student extends Person {
private static final long serialVersionUID = 2L;
String school;
String circles;
public Student(String school, String circles) {
this.school = school;
this.circles = circles;
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
// μμ§λ ¬ν
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream("Student.ser")));
Student student2 = (Student) in.readObject();
in.close();
System.out.println(student2.name);
System.out.println(student2.age);
System.out.println(student2.school);
System.out.println(student2.circles);
}
κ·Έλ¬λ μμ κ΄κ³λ₯Ό μ€μ νλ€ κΈ°μ‘΄μ μ§λ ¬ν λ°μ΄ν°λ₯Ό μμ§λ ¬ν νκ² λλ©΄, Personμμ κ°μ§κ³ μλ nameκ³Ό ageλ₯Ό μ μ μμΌλ―λ‘ κ°κ° κΈ°λ³Έκ°μ ν λΉλ°κ² λλ€.
μΈμμ νμμ μ΄λ¦μ΄ null μΌμλ μκ³ λμ΄κ° 0μΌμλ μλ€.
μ¦, μ΄λ κ² νμ ν΄λμ€λ‘λΆν° λΆλ³ κ°μ²΄λ₯Ό μλ°νλ κ²½μ°κ° μκΈΈ κ²½μ°, readObjectNoData() λ©μλλ₯Ό μμ ν΄λμ€μΈ Person ν΄λμ€ λ΄μ μ μν¨μΌλ‘μ¨ ObjectInputStreamμμ μ§λ ¬ν λ°μ΄ν°μ μλ νλμ λν΄μ κ°μ μ μν λ νΈμΆλλλ‘ μ€μ νλ€.
μμ Personμ κ°λ€μ΄ κΈ°λ³Έκ°μ΄ μλ λ€λ₯Έ κ°μΌλ‘ μ€μ νλ κ²μ΄κΈ° λλ¬Έμ readObjectNoData() λ₯Ό Personμ μ μν΄μΌνλ€.
class Person implements Serializable {
private static final long serialVersionUID = 1L;
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
private void readObjectNoData() {
this.name = "νκΈΈλ";
this.age = 25;
}
}
readObjectNoData() λ₯Ό μ μνκ³ λ€μ μμ§λ ¬νλ₯Ό ν΄λ³΄λ©΄ κΈ°μ‘΄μ name κ³Ό ageμ λ©μλμ μ μν κ°μ΄ κ·Έλλ‘ λ€μ΄μ¨ κ±Έ νμΈ ν μ μλ€.
μ±κΈν€ μμ§λ ¬ν λ°©μ΄
μ΄ν리μΌμ΄μ λ΄μμ μ μΌνκ² μ‘΄μ¬νλ μ±κΈν€(Singleton) κ°μ²΄λ₯Ό λ€λ₯Έ μ»΄ν¨ν°μ μ μ‘νλ κ³Όμ μμ μ§λ ¬ν & μμ§λ ¬νλ₯Ό νκ² λλ©΄ μ μΌμ±μ΄ κΉ¨μ Έ λμ΄μ μ±κΈν€ κ°μ²΄κ° μλκ² λλ λ¬Έμ μ μ΄ μλ€.
μ΄λ¬ν μ±κΈν€μ μμ§λ ¬νμ λμ λ°©μμΌλ‘ μ§λ ¬ν νλ‘μμμ λ€λ£¨μ΄ 보μλ readResolve() λ©μλλ₯Ό μ μνμ¬ κΈ°μ‘΄ μ±κΈν€ κ°μ²΄λ₯Ό λ°ννλλ‘ μ μ΄ν΄μ£Όλ©΄ λλ€. κ·Έλ¦¬κ³ μ±κΈν€ ν΄λμ€μ νλλ€μ λͺ¨λ transient μ μ΄μ μ€μ μ νμ¬ μ§λ ¬νμ μ μΈμν€λλ‘ νλ©΄ μμ§λ ¬νμ μλ²½ν λ°©μ΄κ° κ°λ₯ν΄μ§λ€.
μμΈν κ³Όμ μ μλ ν¬μ€ν μ μ°Έκ³ νκΈΈ λ°λλ€.
μ΄λ κ² μμ§λ ¬νλ₯Ό λ°©μ΄νλ μ¬λ¬κ°μ§ κΈ°λ²μ λν΄μ μμ보μλ€.
νμ§λ§ μ°©κ°νμ§ λ§μμΌ ν κ²μ μμ§λ ¬ν νν°λ§μ΄λ νλ‘μλ₯Ό μ¬μ©ν΄λ μλ²½νκ² μμ§λ ¬ν 곡격μ λ°©μ΄ν μ μλ€λ μ μ΄λ€. κ·Έλμ κ΄λ ¨λ λͺ¨λ² μ¬λ‘λ₯Ό λ°λΌμ μ§λ ¬ν κ°λ₯ ν΄λμ€λ€μ 곡격μ λλΉνλλ‘ μμ±νλ€ νλλΌλ μ¬μ ν μ·¨μ½νκΈ° λλ¬Έμ κ°μ₯ νμ€νκ³ μμ ν λ°©λ²μ μ΄ν리μΌμ΄μ μμ μμ§λ ¬νλ₯Ό μμ μνλ κ²μ΄λ€.
# μ°Έκ³ μλ£
μ΄νν°λΈ μλ° Effective Java 3/E
https://youtu.be/3iypR-1Glm0