Skip to content

Latest commit

ย 

History

History
481 lines (325 loc) ยท 20.7 KB

File metadata and controls

481 lines (325 loc) ยท 20.7 KB

๋ชฉ์ฐจ



์ž๋ฐ” ์ง๋ ฌํ™” ์ดํ•ดํ•˜๊ธฐ - ์‚ฌ์šฉ์‹œ ์ฃผ์˜ํ•  ์ ๊ณผ ์‚ฌ์šฉ์„ ์ถ”์ฒœํ•˜์ง€ ์•Š๋Š” ์ด์œ 

์ง๋ ฌํ™”๋Š” ์ž๋ฐ” ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์™ธ๋ถ€์˜ ์ž๋ฐ” ์‹œ์Šคํ…œ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์—ญ์ง๋ ฌํ™”๋Š” ๋ฐ˜๋Œ€๋กœ ์ง๋ ฌํ™”๋ฅผ ํ†ตํ•ด ๋ณ€ํ™˜๋œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ด๋Ÿฌํ•œ ์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™” ๊ธฐ์ˆ ์€ ๋ฉ”๋ชจ๋ฆฌ์— ์œ„์น˜ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋””์Šคํฌ์— ์ €์žฅ์‹œํ‚ค๊ฑฐ๋‚˜, ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์— ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

ํ˜„์žฌ ์›น์ƒ์—์„œ ์ฃผ๋ ฅ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” JSON๋„ ์—ฌ๋Ÿฌ ์žฅ๋น„๋“ค์ด ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ์ง๋ ฌํ™” ํฌ๋งท์ค‘์˜ ํ•œ ์ข…๋ฅ˜๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฒˆ ๊ธ€์€ ์ž๋ฐ”์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” JDK ์ง๋ ฌํ™” ๋ฐฉ์‹์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณธ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ž๋ฐ” ์ง๋ ฌํ™” ์‚ฌ์šฉ์‹œ ์ฃผ์˜ํ•ด์•ผํ•  ์ ๊ณผ ์™œ ์‚ฌ์šฉ์„ ์ถ”์ฒœํ•˜์ง€ ์•Š๋Š”์ง€ ์ •๋ฆฌํ•ด๋ณธ๋‹ค.


1 ์ž๋ฐ” ์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™”

์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ํ”„๋กœ์„ธ์Šค๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜์–ด์•ผํ•œ๋‹ค.

์ฆ‰, A ์ž๋ฐ” ์‹œ์Šคํ…œ์—์„œ ์ง๋ ฌํ™”ํ•œ ๋‚ด์šฉ์€ ๋‹ค๋ฅธ B ์ž๋ฐ” ์‹œ์Šคํ…œ์—์„œ ์—ญ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ์–ด์•ผํ•œ๋‹ค.

์ž๋ฐ” ์ง๋ ฌํ™”๋Š” ์ด๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ๋Œ€์‹  ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ๋Œ€์ƒ ํด๋ž˜์Šค Serializable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ์ง๋ ฌํ™” - ๊ฐ์ฒด to ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ (ObjectOutputStream)

public final void writeObject(Object o) throws IOException;

์ž๋ฐ” ๊ฐ์ฒด๋ฅผ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ๋กœ ์ง๋ ฌํ™”ํ•  ๋•Œ ObjectOutputStream.writeObject์„ ์‚ฌ์šฉํ•œ๋‹ค.

๋ฆฌํ„ด ๊ฐ’์ด ์™œ ์—†์–ด? ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ObjectOutputStream์€ java.io.OuputStream์„ ์ƒ์†๋ฐ›์œผ๋ฏ€๋กœ, ํ•ด๋‹น ๊ฐ์ฒด ์ƒ์„ฑ์‹œ OutputStream์„ ์ฃผ์ž…๋ฐ›๋Š”๋‹ค.

๊ทธ๋ฆฌ๊ณ  writeObject๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ฃผ์ž…๋ฐ›์€ OutputStream์— ์ง๋ ฌํ™”๋œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ๋ฅผ writeํ•œ๋‹ค. (์ „์†กํ•œ๋‹ค.)

์•„๋ž˜ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค :)


๐Ÿ’โ€โ™‚๏ธ ์—ญ์ง๋ ฌํ™” - ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ to ๊ฐ์ฒด (ObjectInputStream)

public final Object readObject() throws IOException, ClassNotFoundException;

์ง๋ ฌํ™”๋œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ๋ฐ์žํ„ฐ๋ฅผ ๋‹ค์‹œ ์ž๋ฐ” ๊ฐ์ฒด๋กœ ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ ObjectInputStream.readObject๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

ObjectInputStream๋„ java.io.InputStream์„ ์ƒ์†๋ฐ›๊ณ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์ง๋ ฌํ™”๋œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ์˜ Input ํ˜•์‹์— ๋”ฐ๋ผ InputStream์„ ์ฃผ์ž…ํ•˜๊ณ  readObject๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ์ง๋ ฌํ™” ์—ญ์ง๋ ฌํ™” ์˜ˆ์‹œ

์—ฌ๋Ÿฌ๊ฐ€์ง€ ์„ค๋ช…๋ณด๋‹ค ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ง๋ ฌํ™”๋ฅผ ์‚ดํŽด๋ณด์ž.

์šฐ์„  ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”ํ•  ๊ฐ„๋‹จํ•œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค.

Person.java

@Getter
@AllArgsConstructor
public class Person implements Serializable {
    public static final Person EMPTY = new Person("EMPTY", 0, "EMPTY");

    private String name;
    private int age;
    private transient String description;
}

๊ทธ๋ฆฌ๊ณ  ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ค€๋‹ค.

Simple_Serialization_Deserialization_Test.java

@Test
void whenSerializingAndDeserializing_thenCorrect() throws IOException, ClassNotFoundException {
    // given
    Person person = new Person("binghe", 30, "์„ค๋ช…");

    // when
    // serializing ์ง๋ ฌํ™”
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(person); // write (์ง๋ ฌํ™”)
    oos.flush(); oos.close();
    byte[] serializedPerson = baos.toByteArray();
    System.out.println(Base64.getEncoder().encodeToString(serializedPerson));

    // deserializing ์—ญ์ง๋ ฌํ™”
    ByteArrayInputStream bais = new ByteArrayInputStream(serializedPerson);
    ObjectInputStream ois = new ObjectInputStream(bais);
    Object objectMember = ois.readObject(); // read (์—ญ์ง๋ ฌํ™”)
    Person deserializedPerson = (Person) objectMember;

    // then
    assertThat(deserializedPerson.getName()).isEqualTo(person.getName());
    assertThat(deserializedPerson.getAge()).isEqualTo(person.getAge());

    // transient๋Š” ์—ญ์ง๋ ฌํ™” ๋˜์ง€ ์•Š๋Š”๋‹ค. (์—ญ์ง๋ ฌํ™”ํ•˜๋ฉด null๋กœ ์ดˆ๊ธฐํ™”๋œ๋‹ค.)
    assertThat(deserializedPerson.getDescription()).isNull();
    assertThat(deserializedPerson.EMPTY).isEqualTo(person.EMPTY);
}

์‹คํ–‰ํ•ด๋ณด๋ฉด ๋ฌธ์ œ์—†์ด ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผํ•œ๋‹ค :)

์ด๋ ‡๊ฒŒ ๊ต‰์žฅํžˆ ์‰ฝ๊ฒŒ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ์ž๋ฐ” ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”๋Š” static, transient ๊ฐ’์€ ์ง๋ ฌํ™”ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์œ„ ์˜ˆ์‹œ์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, static, transient ๊ฐ’์€ ์ž๋ฐ”์—์„œ ์ง๋ ฌํ™”ํ•˜์ง€์•Š๋Š”๋‹ค.

ํŠนํžˆ transient๋Š” ์—ญ์ง๋ ฌํ™”์‹œ null๋กœ ์ดˆ๊ธฐํ™”๋˜๋ฏ€๋กœ ์ฃผ์˜ํ•ด์•ผํ•œ๋‹ค.


2 ์ž๋ฐ” ์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™” ์ฃผ์˜์‚ฌํ•ญ

์ž๋ฐ” ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”๋Š” ์œ„์™€ ๊ฐ™์ด ์‰ฝ๊ฒŒ ๋น„๊ต์  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ (?) ์ฃผ์˜ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.


2-1 ์ƒ์†๊ณผ ์กฐํ•ฉ

์ž๋ฐ” ์ง๋ ฌํ™”๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ๋Œ€์ƒ์ด java.io.Serializable๋ฅผ ๊ตฌํ˜„ํ•ด์ค˜์•ผํ•œ๋‹ค.

์ด์™€ ๊ด€๋ จํ•ด์„œ ์ฃผ์˜ํ•ด์•ผํ•  ๋ถ€๋ถ„์ด ์žˆ๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ์กฐํ•ฉ ๊ด€๋ จ

Serializable๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”ํ•˜๊ธฐ์œ„ํ•ด์„ , ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๋ชจ๋“  ๊ฐ์ฒด๋„ Serializable๋ฅผ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.

Person.java, Address.java

@Getter
@AllArgsConstructor
public class Person implements Serializable {

    private String name;
    private int age;
    private transient String description;
    private Address address;
}

// Address๋Š” Person์— ์˜ํ•ด ์ฐธ์กฐ๋˜์ง€๋งŒ Serializable์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ ์žˆ๋‹ค.
@Getter
@AllArgsConstructor
public class Address {

    private String address;
}

Serializable_Composition_Test.java

@Test
void whenSerializing_thenThrowNotSerializableException() throws IOException {
    // given
    Address address = new Address("์„œ์šธ"); // not implement serializable object
    Person person = new Person("binghe", 30, "์„ค๋ช…", address);

    // when, then
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    assertThatThrownBy(() -> oos.writeObject(person))
            .isInstanceOf(NotSerializableException.class);
}

์œ„ ์ฝ”๋“œ์—์„œ Address๋Š” Person์— ์˜ํ•ด ์ฐธ์กฐ๋˜์ง€๋งŒ Serializable์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ณ ์žˆ๋‹ค.

๊ทธ๋ž˜์„œ ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์‹คํ–‰์‹œ NotSerializableException๊ฐ€ ๋˜์ ธ์ง„๋‹ค.

์ •๋ฆฌํ•˜๋ฉด, ๋งŒ์•ฝ ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋“ค์ด Serializable๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ ์žˆ์ง€ ์•Š์œผ๋ฉด, ์œ„์™€ ๊ฐ™์ด NotSerializableException ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ด๋Š” Collection์˜ ์š”์†Œ๋„ ํฌํ•จ์ด๋‹ค. Collection์˜ ์š”์†Œ๋„ ๋ชจ๋‘ Serializable์„ ๊ตฌํ˜„ํ•ด์ค˜์•ผํ•œ๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ์ƒ์† ๊ด€๋ จ

Serializable๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜๋Š” ํ•˜์œ„ ํด๋ž˜์Šค๋„ ์ž๋™์œผ๋กœ ๋ชจ๋‘ Serializable๋ฅผ ๊ตฌํ˜„ํ•˜๊ฒŒ๋œ๋‹ค.

์ด๋Š” ๋ชจ๋“  ํ•˜์œ„ ํด๋ž˜์Šค๋„ Serializable๋กœ๋ถ€ํ„ฐ ์ž์œ ๋กœ์šธ ์ˆ˜ ์—†์œผ๋ฉฐ, ์ž๋ฐ” ์ง๋ ฌํ™” ์‚ฌ์šฉ์‹œ ์ฃผ์˜ํ•ด์•ผํ•  ์ ์„ ๋ชจ๋‘ ์ฃผ์˜ํ•ด์ค˜์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์ฆ‰, ํ•˜์œ„ ํด๋ž˜์Šค๋„ ๋ชจ๋‘ Serializable์ด ์ž๋™์œผ๋กœ ๋ชจ๋‘ ๊ตฌํ˜„ํ•˜๊ฒŒ๋˜๋ฏ€๋กœ, ์ด๋ฅผ ์ธ์ง€ํ•˜๊ณ ์žˆ์–ด์•ผํ•œ๋‹ค.


2-2 ์—ญ์ง๋ ฌํ™”์‹œ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ ํƒ€์ž…์ด ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜ ํŒจํ‚ค์ง€ ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๐Ÿ’โ€โ™‚๏ธ ์ž๋ฐ” ์ง๋ ฌํ™”๋Š” ์ง๋ ฌํ™”์‹œ ๊ฐ์ฒด์˜ ๋ฉ”ํƒ€ ์ •๋ณด๋„ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์— ๊ฐ™์ด ์ €์žฅํ•œ๋‹ค.

์ง๋ ฌํ™”ํ•œ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ Base64๋กœ ์ธ์ฝ”๋”ฉํ›„ ๋””์ฝ”๋”ฉํ•œ ๊ฒฐ๊ณผ

๏ฟฝ๏ฟฝsr๏ฟฝ/com.binghe.ex05.SoftwareDeveloper=	๏ฟฝn;๏ฟฝ๏ฟฝ๏ฟฝL๏ฟฝ๏ฟฝlanguaget๏ฟฝ๏ฟฝLjava/lang/String;xr๏ฟฝ$com.binghe.ex05.Person๏ฟฝ๏ฟฝ}f๏ฟฝ=๏ฟฝ๏ฟฝ๏ฟฝI๏ฟฝ๏ฟฝageL๏ฟฝ๏ฟฝnameq๏ฟฝ~๏ฟฝ๏ฟฝxp๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝt๏ฟฝ๏ฟฝbinghet๏ฟฝ๏ฟฝjava

์œ„์™€ ๊ฐ™์ด String, com.binghe.ex05.Person๋“ฑ๋“ฑ์˜ ๋ฉ”ํƒ€ ์ •๋ณด๋ฅผ ๋ชจ๋‘ ๊ฐ™์ด ์ €์žฅํ•œ๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ์—ญ์ง๋ ฌํ™”์‹œ ํ•ด๋‹น ๋ฉ”ํƒ€ ์ •๋ณด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์—ญ์ง๋ ฌํ™”ํ•œ๋‹ค.

์ง๋ ฌํ™”๋œ ์ •๋ณด๋ฅผ ๋‹ค์‹œ ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ, ํ•ด๋‹น ๋ฉ”ํƒ€ ์ •๋ณด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์—ญ์ง๋ ฌํ™”๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ๋ฌธ์ œ๋Š” ๋ฉ”ํƒ€ ์ •๋ณด์— ๋‚˜์™€์žˆ๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์˜ ํƒ€์ž…์ด ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜, ํŒจํ‚ค์ง€ ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Person.java

package comm.binghe.ex05;

@Getter
public class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private int age;
    private Address address;
}

Address.java

package comm.binghe.ex05;
@Getter
public class Address implements Serializable {

    private String address;

    public Address(String address) {
        this.address = address;
    }
}

์ด์ œ Person์„ ์ง๋ ฌํ™”ํ•œ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

<!-- ์ง๋ ฌํ™”ํ›„ Base64๋กœ ์ธ์ฝ”๋”ฉํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋””์ฝ”๋”ฉํ•œ ๊ฒฐ๊ณผ -->
๏ฟฝ๏ฟฝsr๏ฟฝ"com.binghe.ex05.Person๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝI๏ฟฝ๏ฟฝageL๏ฟฝ๏ฟฝaddresst๏ฟฝ%Lcom.binghe.ex05/Address;L๏ฟฝ๏ฟฝnamet๏ฟฝ๏ฟฝLjava/lang/String;xp๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝsr๏ฟฝ#com.binghe.ex05.AddressJtฬ—$๏ฟฝ๏ฟฝ๏ฟฝL๏ฟฝ๏ฟฝaddressq๏ฟฝ~๏ฟฝ๏ฟฝxpt๏ฟฝ๏ฟฝseoult๏ฟฝ๏ฟฝbinghe

์ด๋•Œ Address์˜ ํŒจํ‚ค์ง€ ์œ„์น˜๋ฅผ ๋ณ€๊ฒฝํ•ด๋ณธ๋‹ค.

com.binghe.ex05 -> com.binghe.ex05.address

๊ทธ๋ฆฌ๊ณ  ์œ„์—์„œ ์ง๋ ฌํ™”ํ•œ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ์—ญ์ง๋ ฌํ™”ํ•ด๋ณด๋ฉด ClassNotFoundException๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ง๋ ฌํ™”ํ•œ ๊ฒฐ๊ณผ์—์„œ ์—ญ์ง๋ ฌํ™”์‹œ com.binghe.ex05.Address๋ฅผ ์ฐพ๋Š”๋ฐ, Address๋Š” com.binghe.ex05.address.Address๋กœ ํŒจํ‚ค์ง€๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๊ธฐ๋•Œ๋ฌธ์— ํด๋ž˜์Šค๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋Š” ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ํŒจํ‚ค์ง€๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํƒ€์ž…์ด ๋ณ€๊ฒฝ๋˜๋ฉด InvalidClassException๊ฐ€ ๋˜์ ธ์ง„๋‹ค.

์‹ฌ์ง€์–ด int๋ฅผ long์œผ๋กœ ๋ณ€๊ฒฝํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Person.java

@Getter
public class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private int age;
}

์œ„ Person์„ ์ง๋ ฌํ™”ํ›„ age์˜ ํƒ€์ž…์„ long์œผ๋กœ ๋ณ€๊ฒฝํ•ด๋„ InvalidClassException๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๋‹น์—ฐํžˆ ์ฐธ์กฐ ํƒ€์ž…์˜ ๊ฐ์ฒด๋„ ๋ณ€๊ฒฝ๋˜๋ฉด InvalidClassException๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ์ •๋ฆฌ

  • ์ž๋ฐ”๋Š” ์ง๋ ฌํ™”์‹œ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์˜ ํŒจํ‚ค์ง€์™€ ํƒ€์ž…์„ ๋ฉ”ํƒ€ ์ •๋ณด๋กœ ์ €์žฅํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์—ญ์ง๋ ฌํ™”์‹œ ์ด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์—ญ์ง๋ ฌํ™”ํ•œ๋‹ค.
  • ๋งŒ์•ฝ ์—ญ์ง๋ ฌํ™”์‹œ ๊ธฐ์กด์˜ ํด๋ž˜์Šค ๋ฉค๋ฒ„๋ณ€์ˆ˜ ํŒจํ‚ค์ง€ ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋ฉด, ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ClassNotFoundException๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • ๋งŒ์•ฝ ์—ญ์ง๋ ฌํ™”์‹œ ๊ธฐ์กด์˜ ํด๋ž˜์Šค ๋ฉค๋ฒ„๋ณ€์ˆ˜ ํƒ€์ž…์ด ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋ฉด, ์—ญ์ง๋ ฌํ™”์‹œ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ InvalidClassException๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • ์ด์™ธ์—๋„, ์—ญ์ง๋ ฌํ™”ํ•œ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ์•…์˜์ ์œผ๋กœ ์ˆ˜์ •ํ•˜์—ฌ ๋ณด์•ˆ์ ์ธ ๊ณต๊ฒฉ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ ํ•œ๋‹ค.

2-3 ์—ญ์ง๋ ฌํ™”์‹œ ํด๋ž˜์Šค ๊ตฌ์กฐ ๋ณ€๊ฒฝ ๋ฌธ์ œ (Serial Version UID)

์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ์˜ ํด๋ž˜์Šค์˜ ๋ฒ„์ „์ด ์„œ๋กœ ๋‹ค๋ฅด๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ์•ž์„œ ์‚ดํŽด๋ณธ Person ํด๋ž˜์Šค๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์—ญ์ง๋ ฌํ™”์‹œ ํด๋ž˜์Šค ๊ตฌ์กฐ ๋ณ€๊ฒฝ ๋ฌธ์ œ๋ฅผ ์‚ดํŽด๋ณธ๋‹ค.

Person.java

@Getter
public class Person implements Serializable {
    private String name;
    private int age;
}

Person์„ ์ง๋ ฌํ™”ํ•˜๊ณ  Base64๋กœ ์ธ์ฝ”๋”ฉํ•œ ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

<!-- name: binghe, age: 30 ์œผ๋กœ ๊ฐ์ฒด ์ƒ์„ฑํ›„ ์ง๋ ฌํ™” ๋ฐ Base64 ์ธ์ฝ”๋”ฉ -->
rO0ABXNyACRleDA0X3NlcmlhbGl6YXRpb25fdmVyc2lvblVJRC5QZXJzb26/7herOgpoOAIAAkkAA2FnZUwABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cAAAAB50AAZiaW5naGU=

์ด ๋ฌธ์ž์—ด์„ ๋ฐ”๋กœ ์—ญ์ง๋ ฌํ™”ํ•˜๋ฉด Person์œผ๋กœ ์ž˜ ๋ณ€ํ™˜๋œ๋‹ค. (๋ฌผ๋ก  ํ…Œ์ŠคํŠธํ•  ๋•Œ์— ๋ฐ˜๋“œ์‹œ ํŒจํ‚ค์ง€๋„ ๋™์ผํ•ด์•ผํ•œ๋‹ค.)

๊ทธ๋ ‡๋‹ค๋ฉด Person ํด๋ž˜์Šค์˜ ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์ง๋ ฌํ™”ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ๋ ๊นŒ? (ex. ๋ฉค๋ฒ„๋ณ€์ˆ˜ ์ถ”๊ฐ€)

Person.java

@Getter
public class Person implements Serializable {
    private String name;
    private int age;

    // ์ง๋ ฌํ™”ํ›„ ์†์„ฑ ์ถ”๊ฐ€
    private String description;
}

Person์— description์ด๋ผ๋Š” ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ์ด์ „์— name๊ณผ age๋งŒ ์กด์žฌํ•˜๋˜ ์ƒํƒœ์—์„œ ์ง๋ ฌํ™”ํ•œ Person์„ ๋‹ค์‹œ ์—ญ์ง๋ ฌํ™”ํ•ด๋ณธ๋‹ค.

๊ทธ๋Ÿผ ์•„๋ž˜์™€ ๊ฐ™์ด InvalidClassException์ด ๋ฐœ์ƒํ•œ๋‹ค.

๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์„œ ํ™•์ธํ•ด๋ณด์ž.

Serializable_UID_Test.java

@Test
void whenDeserializingChangedObject_thenThrowInvalidClassException() throws IOException, ClassNotFoundException {
    // given (name, age๋งŒ ๊ฐ€์ง„ ex04_serialization_versionUID.Person ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํ™”ํ•œ base64 ๋ฐ์ดํ„ฐ)
    String deserializedPersonBase64 = "rO0ABXNyACRleDA0X3NlcmlhbGl6YXRpb25fdmVyc2lvblVJRC5QZXJzb26/7herOgpoOAIAAkkAA2FnZUwABG5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cAAAAB50AAZiaW5naGU=";
    byte[] deserializedPersonBase = Base64.getDecoder().decode(deserializedPersonBase64);

    // when
    ByteArrayInputStream bais = new ByteArrayInputStream(deserializedPersonBase);
    ObjectInputStream ois = new ObjectInputStream(bais);

    // then
    assertThatThrownBy(() -> ois.readObject())
        .isInstanceOf(InvalidClassException.class);
//        ois.readObject();
}

๋ฌธ์ œ ์—†์ด ํ†ต๊ณผํ•œ๋‹ค :)


์ž์„ธํ•œ ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

java.io.InvalidClassException: ex04_serialization_versionUID.Person; local class incompatible: stream classdesc serialVersionUID = -4616726543827572680, local class serialVersionUID = 7715257156664215348

๋ณดํ†ต ๊ฐœ๋ฐœ์ž๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์€ description ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋˜์–ด๋„ ๊ธฐ์กด ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋Š” ๊ทธ๋Œ€๋กœ ์ฑ„์›Œ์ง€๊ณ  ์ƒˆ๋กœ์šด ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋Š” null๋กœ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

ํ•˜์ง€๋งŒ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.. ์˜ˆ์™ธ๋ฅผ ์ž˜ ์ฝ์–ด๋ณด๋ฉด Person์˜ serialVersionUID๊ฐ€ ์ผ์น˜ํ•˜์ง€์•Š์•„์„œ ๋ฐœ์ƒํ•œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์•Œ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์ž๋ฐ”๋Š” ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํ™”ํ•  ๋•Œ serialVersionUID์„ ์ƒ์„ฑํ•˜๊ณ , ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ์˜ ์ƒ์„ฑํ•œ serialVersionUID์™€ ๊ฐ™์ง€์•Š์œผ๋ฉด InvalidClassException๋ฅผ ๋˜์ง„๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์ง๋ ฌํ™”ํ•  ๋•Œ์˜ ํด๋ž˜์Šค ๋ฒ„์ „๊ณผ ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ์˜ ํด๋ž˜์Šค ๋ฒ„์ „์ด ์„œ๋กœ ๋‹ค๋ฅด๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ์˜๋ฏธ.


๐Ÿ’โ€โ™‚๏ธ ์ž๋ฐ” ์ง๋ ฌํ™” ์ŠคํŽ™์„ ์‚ดํŽด๋ณด๋ฉด ์ง๋ ฌํ™” ๊ฐ์ฒด์— serialVersionUID๋ฅผ ํ•ญ์ƒ ์ •์˜ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.


์ถœ์ฒ˜: https://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100

SUID (serialVersionUID)๋Š” ํ•„์ˆ˜ ๊ฐ’์ด ์•„๋‹ˆ์ง€๋งŒ, ์ง์ ‘ ๊ธฐ์ˆ ํ•˜์ง€ ์•Š์œผ๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ SUID ์ •๋ณด๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉฐ, ์ž๋ฐ” ์ง๋ ฌํ™” ์ŠคํŽ™ ๊ทธ๋Œ€๋กœ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ ํด๋ž˜์Šค์˜ ํ•ด์‹œ ๊ฐ’์ด ์‚ฌ์šฉ๋œ๋‹ค.

๋ฌธ์ œ๋Š” SUID๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋ฉด ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”์‹œ ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ด๋‹ค... ๊ทธ๋ž˜์„œ ์œ„ ์ŠคํŽ™์—์„œ๋„ ํ˜ธํ™˜ ๊ฐ€๋Šฅํ•œ ํด๋ž˜์Šค๋Š” SUID ๊ฐ’์ด ๊ณ ์ •๋˜์–ด์žˆ์–ด์•ผํ•œ๋‹ค๊ณ ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  "์กฐ๊ธˆ์ด๋ผ๋„ ์—ญ์ง๋ ฌํ™” ๋Œ€์ƒ ํด๋ž˜์Šค ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒํ•ด์•ผ ๋œ๋‹ค."์ •๋„์˜ ๋ฏผ๊ฐํ•œ ์‹œ์Šคํ…œ์ด ์•„๋‹Œ ์ด์ƒ์€ ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ์— ์ง์ ‘ serialVersionUID๊ฐ’์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค๊ณ ํ•œ๋‹ค.

์ฆ‰, ๋ฏผ๊ฐํ•œ ์‹œ์Šคํ…œ์ด ์•„๋‹ˆ๋ผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ง๋ ฌํ™” ๋Œ€์ƒ์˜ ํด๋ž˜์Šค์— serialVersionUID๋ฅผ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.

Person.java

@Getter
public class Person implements Serializable {
    // SUID ๊ฐ’ ๋ช…์‹œ.
    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

    // ์ง๋ ฌํ™”ํ›„ ์†์„ฑ ์ถ”๊ฐ€
    private String description;
}

์ด๋ ‡๊ฒŒ SUID๋ฅผ ์ •์˜ํ•ด์ฃผ๋ฉด, ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ–ˆ์„๋•Œ null๋กœ ๋„ฃ์–ด์ฃผ๋ฉฐ, ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์‚ญ์ œํ•ด๋„ ์˜ˆ์™ธ ์—†์ด ํ•ด๋‹น ๊ฐ’ ์ž์ฒด๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋‚˜๋จธ์ง€ ๊ฐ’๋“ค๋งŒ ์—ญ์ง๋ ฌํ™”ํ•ด์ค€๋‹ค.


๐Ÿ’โ€โ™‚๏ธ ์ •๋ฆฌ

  • ์ž๋ฐ”๋Š” ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํ™”ํ•  ๋•Œ ์ง๋ ฌํ™” ๊ฒฐ๊ณผ์— serialVersionUID์„ ์ƒ์„ฑํ•˜์—ฌ ๋ฉ”ํƒ€ ์ •๋ณด๋กœ ์ €์žฅํ•œ๋‹ค.
  • ์‚ฌ์šฉ์ž๊ฐ€ ๋”ฐ๋กœ ์ง€์ •ํ•ด์ฃผ์ง€์•Š์œผ๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ ํด๋ž˜์Šค์˜ ํ•ด์‹œ ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ์ €์žฅํ•œ๋‹ค.
  • ๋ฌธ์ œ๋Š” ์—ญ์ง๋ ฌํ™”์‹œ์˜ ์ €์žฅ๋œ SUID์™€ ํ˜„์žฌ ํด๋ž˜์Šค์˜ SUID๊ฐ€ ๋‹ค๋ฅด๋ฉด InvalidClassException๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
    • ์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ์˜ ํด๋ž˜์Šค์˜ ๋ฒ„์ „์ด ์„œ๋กœ ๋‹ค๋ฅด๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • "์กฐ๊ธˆ์ด๋ผ๋„ ์—ญ์ง๋ ฌํ™” ๋Œ€์ƒ ํด๋ž˜์Šค ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒํ•ด์•ผํ•˜๋Š” ์˜ˆ๋ฏผํ•œ ์‹œ์Šคํ…œ"์ด ์•„๋‹ˆ๋ผ๋ฉด ์ง๋ ฌํ™”ํ•  ํด๋ž˜์Šค์— serialVersionUID๋ฅผ ๋ช…์‹œํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

3 ์™œ ์‚ฌ์šฉํ•˜์ง€ ๋ง๋ผ๋Š” ๊ฒƒ์ธ๊ฐ€?

์‚ฌ์‹ค ์ž๋ฐ” ์ง๋ ฌํ™”์™€ ๊ด€๋ จ๋œ ์ด์Šˆ๋Š” ๊ต‰์žฅํžˆ ์ž˜ ์•Œ๋ ค์ ธ์žˆ๋‹ค.. ๊ทธ๋ฆฌ๊ณ  ์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”์˜ ์•„์ดํ…œ 85์—์„  ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ•์กฐํ•œ๋‹ค.

  • "The best way to avoid serialization exploits is to never deserialize anything."
  • "There is no reason to use Java serialization in any new system you write."

๊ฐ€๋Šฅํ•œ ์—ญ์ง๋ ฌํ™”๋ฅผ ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์œผ๋ฉฐ, ์ƒˆ๋กœ์šด ์‹œ์Šคํ…œ์—์„  ์ž๋ฐ” ์—ญ์ง๋ ฌํ™”๋ฅผ ์‚ฌ์šฉํ•  ์ด์œ ๊ฐ€ ์ „ํ˜€ ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์ž๋ฐ” ์—ญ์ง๋ ฌํ™” ์‚ฌ์šฉ์„ ์ถ”์ฒœํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ•ํ•˜๊ฒŒ ๊ฐ•์กฐํ•œ๋‹ค.


๊ทธ๋ž˜์„œ ํ•„์ž๋Š” ๋ช‡๋ช‡ ์ž๋ฃŒ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์‚ฌ์šฉํ•ด๋ณด๋ฉด์„œ JDK ์ง๋ ฌํ™” ์ถ”์ฒœํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ์ •๋ฆฌํ•ด๋ณด์•˜๋‹ค.

  1. ๋ฒ„์ €๋‹ ์ด์Šˆ
    • ์‚ฌ์šฉ์‹œ ์ฃผ์˜ ์‚ฌํ•ญ์—์„œ ์–˜๊ธฐํ–ˆ๋“ฏ์ด, ์ง๋ ฌํ™”ํ•  ๋•Œ์™€ ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ์˜ ํด๋ž˜์Šค ๋ฒ„์ €๋‹์ด ๋‹ค๋ฅด๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
    • ๋ฌธ์ œ๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„์— ์ด๋ฅผ ํ™•์ธํ•  ๋ฐฉ๋ฒ•์ด ์—†์œผ๋ฉฐ, ๋Ÿฐํƒ€์ž„์— ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ์•ผ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ๋œ๋‹ค.
    • ๋˜ํ•œ, ์ง๋ ฌํ™”ํ•˜๋Š” ํด๋ž˜์Šค์˜ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ ๋ฒ„์ „์ด ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ๋Š” ๊ต‰์žฅํžˆ ๋งŽ๋‹ค... ์ง๋ ฌํ™”๋กœ์ธํ•ด ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ์ด ์ž์œ ๋กญ์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐ๋“ ๋‹ค.
    • ๋ฌผ๋ก  SUID๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•ด์„œ ๋ฒ„์ €๋‹ ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆœ ์žˆ์ง€๋งŒ, ์ข‹์€ ๊ตฌ์กฐ๋Š” ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐ๋“ ๋‹ค.
  2. Serializable ์ง€์˜ฅ
    • Serializable์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋งŒ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ๋  ์ˆ˜ ์žˆ๋‹ค.
    • ๋ฌธ์ œ๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ ์žˆ๋Š” ํด๋ž˜์Šค๊ฐ€ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”ํ•˜๋ ค๋ฉด ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋„ ๋ชจ๋‘ Serializable์„ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. (์ƒ์†๋„ ๋™์ผ)
    • ์ด๋Š” ์‚ฌ์šฉ์‹œ ์ฃผ์˜ ์‚ฌํ•ญ์—๋„ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ด๊ธฐ๋„ํ•œ๋ฐ, ์ด ํŠน์ง•์œผ๋กœ์ธํ•ด ๋ณต์žกํ•œ ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„๋ฅผ ๊ฐ€์ง„๊ฒฝ์šฐ Serializable ์ง€์˜ฅ์— ๋น ์งˆ ์ˆ˜ ์žˆ๋‹ค.
    • ๋˜ํ•œ, ํ•„์ž ์ƒ๊ฐ์—” Serializable์— ์˜์กดํ•˜๋Š” ์ฝ”๋“œ ์ž์ฒด๊ฐ€ JDK์˜ ๊ธฐ๋ณธ ์ŠคํŽ™์ž„์—๋„ POJO์˜ ๋น„์นจํˆฌ์„ฑ์„ ๊นจํŠธ๋ฆฌ๋Š”๊ฒŒ ์•„๋‹Œ๊ฐ€ ์ƒ๊ฐ๋“ ๋‹ค.
  3. ์šฉ๋Ÿ‰ ๋ฌธ์ œ
    • ์‚ฌ์šฉ์‹œ ์ฃผ์˜ ์‚ฌํ•ญ์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, ์ž๋ฐ” ์ง๋ ฌํ™”๋Š” ์ง๋ ฌํ™”์‹œ ๋ฉค๋ฒ„๋ณ€์ˆ˜์˜ ํŒจํ‚ค์ง€์™€ ํƒ€์ž…์„ ๋ฉ”ํƒ€ ์ •๋ณด๋กœ ์ €์žฅํ•œ๋‹ค.
    • ์ด๋Š” ์บ์‹œ ์„œ๋ฒ„์™€ ๊ฐ™์€ ๊ณณ์— ์‚ฌ์šฉ๋œ๋‹ค๋ฉด ์šฉ๋Ÿ‰ ๋ฌธ์ œ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ํ•ญ์ƒ ์กฐ์‹ฌํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
  4. ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ
    • ์ž๋ฐ” ์ง๋ ฌํ™”๋Š” ์ž๋ฐ” ์‹œ์Šคํ…œ๊ฐ„์˜ ์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™”๋งŒ ์ง€์›ํ•œ๋‹ค.
    • ์ž๋ฐ”์—์„œ๋งŒ ์ฝ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋‹ค๋ฅธ ์‹œ์Šคํ…œ๊ณผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๊ฐ„์˜ ํ˜ธํ™˜์ด ์ „ํ˜€ ์•ˆ๋œ๋‹ค.
  5. ๋ณด์•ˆ ์ด์Šˆ
    • ์ง๋ ฌํ™”๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ œ๋Œ€๋กœ ๊ฒ€์ฆ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ณด์•ˆ ์•…์šฉ์— ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๊ณต๊ฒฉ์ž๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—ญ์ง๋ ฌํ™”๋  ๋•Œ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋Š” ์ง๋ ฌํ™”๋œ ๋ฐ์ดํ„ฐ์— ์•…์„ฑ ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋•Œ ์™ธ๋ถ€์™€ ํ†ต์‹ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋„ฃ๋Š”๋‹ค๋ฉด ์ž์นซ ํ•ดํ‚น๋˜์–ด ๋ณด์•ˆ์ ์œผ๋กœ ํฐ ์ด์Šˆ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ