Item 87. Custom Serialization Form

์ปค์Šคํ…€ ์ง๋ ฌํ™” ํ˜•ํƒœ๋ฅผ ๊ณ ๋ คํ•ด๋ณด๋ผ

์ง๋ ฌํ™”๋ฅผ ๊ผญ ์‚ฌ์šฉํ•ด์•ผํ•˜๊ณ , ๊ธฐ๋ณธ ์ง๋ ฌํ™” ํ˜•ํƒœ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. (๊ธฐ๋ณธ ์ง๋ ฌํ™” ํ˜•ํƒœ๊ฐ€ ์ ํ•ฉํ•˜๋”๋ผ๋„ ๋ถˆ๋ณ€์‹ ๋ณด์žฅ๊ณผ ๋ณด์•ˆ์„ ์œ„ํ•ด readObject ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.)

  • ์ง์ ‘ ์„ค๊ณ„ํ–ˆ์„ ๋•Œ, ๊ธฐ๋ณธ ์ง๋ ฌํ™” ํ˜•ํƒœ์™€ ๊ฑฐ์˜ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ๊ฒฝ์šฐ

  • ๊ฐ์ฒด์˜ ๋ฌผ๋ฆฌ์  ํ‘œํ˜„๊ณผ ๋…ผ๋ฆฌ์  ๋‚ด์šฉ์ด ๊ฐ™์€ ๊ฒฝ์šฐ

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

public final class StringList implements Serializable {

    private int size = 0;
    private Entry head = null;

    private static class Entry implements Serializable {

        String data;
        Entry next;
        Entry previous;
    }

    // ...
}

์œ„ ํด๋ž˜์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

  • ๋…ผ๋ฆฌ์ : ์ผ๋ จ์˜ ๋ฌธ์ž์—ด์„ ํ‘œํ˜„

  • ๋ฌผ๋ฆฌ์ : ๋ฌธ์ž์—ด๋“ค์„ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ, ๊ฐ ๋…ธ๋“œ์˜ ์–‘๋ฐฉํ˜• ์—ฐ๊ฒฐ ์ •๋ณด๊ฐ€ ๊ธฐ๋ก ๋จ

์ด์ฒ˜๋Ÿผ ๋ฌผ๋ฆฌ์ /๋…ผ๋ฆฌ์  ํ‘œํ˜„์— ์ฐจ์ด๊ฐ€ ์กด์žฌํ•  ๋•Œ ๊ธฐ๋ณธ ์ง๋ ฌํ™” ํ˜•ํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋„ค ๊ฐ€์ง€ ๋ฉด์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

  1. ๊ณต๊ฐœ API๊ฐ€ ํ˜„์žฌ ๋‚ด๋ถ€ ํ‘œํ˜„ ๋ฐฉ์‹์— ๋ฌถ์ž„: ๋‚ด๋ถ€ ๊ตฌํ˜„ ๋ฐฉ์‹์œผ๋กœ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„ ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์—†์Œ

  2. ๋ถˆํ•„์š”ํ•œ ๊ณต๊ฐ„ ์ฐจ์ง€: ๊ฐ’ ๋ฐ์ดํ„ฐ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋‚ด๋ถ€ ๊ตฌํ˜„์ธ ์—ฐ๊ฒฐ ์ •๋ณด๊นŒ์ง€ ์ง๋ ฌํ™”๋˜์–ด ์ €์žฅ๋˜์–ด ๋ถˆํ•„์š”ํ•œ ๊ณต๊ฐ„ ์ฐจ์ง€

  3. ๋ถˆํ•„์š”ํ•œ ์‹œ๊ฐ„ ์†Œ๋ชจ: ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ๊ทธ ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์žˆ๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค๋„ ์ง๋ ฌํ™” ํ•˜๋Š”๋ฐ, ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„์˜ ์œ„์ƒ์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์—†์–ด ์ง๋ ฌํ™”์— ๋งŽ์€ ์‹œ๊ฐ„์ด ์†Œ์š”๋จ

  4. ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ: ๊ธฐ๋ณธ ์ง๋ ฌํ™” ๊ณผ์ •์€ ๊ฐ์ฒด ๊ทธ๋ž˜ํ”„๋ฅผ ์žฌ๊ท€ ์ˆœํšŒํ•˜๋Š”๋ฐ, ๊ทธ ๊ณผ์ •์—์„œ ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ

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

public final class StringList implements Serializable {

    // transient ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง๋ ฌํ™” ๋Œ€์ƒ์—์„œ ์ œ์™ธ
    // transient ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํ•„๋“œ๋“ค์€ ์—ญ์ง๋ ฌํ™”๋  ๋•Œ ํ•ด๋‹น ํƒ€์ž…์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”๋จ
    private transient int size = 0;
    private transient Entry head = null;

    // Serializable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์—†์•  Entry ํด๋ž˜์Šค๋ฅผ ์ง๋ ฌํ™” ๋Œ€์ƒ์—์„œ ์ œ์™ธ
    private static class Entry {

        String data;
        Entry next;
        Entry previous;
    }

    // ์ง€์ •ํ•œ ๋ฌธ์ž์—ด์„ ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€
    public final void add(String s) {
        // ...
    }

    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        s.writeInt(size);

        // ๋ชจ๋“  ์›์†Œ๋ฅผ ์˜ฌ๋ฐ”๋ฅธ ์ˆœ์„œ๋กœ ๊ธฐ๋ก
        for (Entry e = head; e != null; e = e.next) {
            s.writeObject(e.data);
        }
    }

    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
        s.defaultReadObject();
        int numElements = s.readInt();

        // ๋ชจ๋“  ์›์†Œ๋ฅผ ์ฝ์–ด ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€
        for (int i = 0; i < numElements; i++) {
            add((String) s.readObject());
        }
    }

    // ...
}

๋ณ€๊ฒฝ ๋œ ์ฃผ์š” ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. size, head ํ•„๋“œ transient ์ ์šฉ: ์ง๋ ฌํ™” ๋Œ€์ƒ์—์„œ ์ œ์™ธ

  2. Entry ํด๋ž˜์Šค Serializable ์ธํ„ฐํŽ˜์ด์Šค ์ œ๊ฑฐ: ์ง๋ ฌํ™” ๋Œ€์ƒ์—์„œ ์ œ์™ธ

  3. writeObject, readObject ๋ฉ”์„œ๋“œ ๊ตฌํ˜„: ์ง๋ ฌํ™” ํ˜•ํƒœ๋ฅผ ์ปค์Šคํ…€ํ•˜์—ฌ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ์ˆ˜ํ–‰

  4. defaultWriteObject, defaultReadObject ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ: ํ–ฅํ›„ ๋ฆด๋ฆฌ์Šค์—์„œ transient ํ•„๋“œ๊ฐ€ ์ถ”๊ฐ€/์ œ๊ฑฐ ์‹œ ํ˜ธํ™˜ ๊ฐ€๋Šฅ

๋‹ค๋ฅธ ์ž๋ฃŒ๊ตฌ์กฐ ์‚ฌ์šฉ ์‹œ

์‚ฌ์‹ค StringList์˜ ๊ธฐ๋ณธ ์ง๋ ฌํ™” ํ˜•ํƒœ๋„ ๋ฌธ์ œ๊ฐ€ ๋งŽ์•˜์ง€๋งŒ, ๋” ๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ํ•ด์‹œํ…Œ์ด๋ธ”์˜ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. ํ•ด์‹œํ…Œ์ด๋ธ”์€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ํ‚ค-๊ฐ’ ์—”ํŠธ๋ฆฌ๋ฅผ ๋‹ด์€ ํ•ด์‹œ ๋ฒ„ํ‚ท์„ ์ฐจ๋ก€๋กœ ๋‚˜์—ดํ•œ ํ˜•ํƒœ๋กœ ์ €์žฅ

  2. ์–ด๋–ค ์—”ํŠธ๋ฆฌ๋ฅผ ์–ด๋–ค ๋ฒ„ํ‚ท์— ๋‹ด์„ ์ง€๋Š” ํ‚ค์—์„œ ๊ตฌํ•œ ํ•ด์‹œ์ฝ”๋“œ๋กœ ๊ฒฐ์ก๋˜๋Š”๋ฐ, ๊ณ„์‚ฐํ•  ๋•Œ๋งˆ๋‹ค ๋‹ฌ๋ผ์ง€๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Œ

  3. ์ง๋ ฌํ™” ํ›„ ์—ญ์ง๋ ฌํ™”ํ•˜๋ฉด ๋‹ค๋ฅธ ํ•ด์‹œ์ฝ”๋“œ๊ฐ€ ๋‚˜์˜ค๊ฒŒ ๋˜์–ด, ํ›ผ์†๋œ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ์Œ

๊ทธ ์™ธ ์ฃผ์˜์‚ฌํ•ญ

  • transient ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํ•„๋“œ๋“ค์€ ์—ญ์ง๋ ฌํ™”๋  ๋•Œ ํ•ด๋‹น ํƒ€์ž…์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”๋จ

  • ํด๋ž˜์Šค ๋‚ด์—์„œ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ์‹œ, writeObject, readObject ๋ฉ”์„œ๋“œ์—์„œ๋„ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ

  • ์ง๋ ฌํ™” ๊ฐ€๋Šฅ ํด๋ž˜์Šค ๋ชจ๋‘์— ์ง๋ ฌ ๋ฒ„์ „ UID๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋ถ€์—ฌ

    • ์ง๋ ฌ ๋ฒ„์ „ UID๊ฐ€ ์ผ์œผํ‚ค๋Š” ์ž ์žฌ์ ์ธ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ฐ€๋Šฅ

    • ๋Ÿฐํƒ€์ž„์—์„œ ์ƒ์„ฑํ•˜๋Š” ์‹œ๊ฐ„ ๋‹จ์ถ• ๊ฐ€๋Šฅ

    • ๊ธฐ์กด ๋ฒ„์ „ ํด๋ž˜์Šค ํ˜ธํ™˜์„ฑ ์œ ์ง€ ์‹œ UID ์œ ์ง€ / ํ˜ธํ™˜์„ฑ ๋Š์„ ์‹œ UID ๋ณ€๊ฒฝ

Last updated