Skip to content

Latest commit

ย 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
ย 
ย 

README.md

Title

private ์ƒ์„ฑ์ž๋‚˜ ์—ด๊ฑฐ ํƒ€์ž…์œผ๋กœ ์‹ฑ๊ธ€ํ„ด์ž„์„ ๋ณด์ฆํ•˜๋ผ

์ž๋ฐ”์˜ Serializable

๋ฌด์—‡์ธ๊ฐ€?

  • ์ž๋ฐ” ์‹œ์Šคํ…œ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์™ธ๋ถ€์˜ ์ž๋ฐ” ์‹œ์Šคํ…œ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ”์ดํŠธ(byte) ํ˜•ํƒœ๋กœ ํ…Œ์ดํ„ฐ ๋ณ€ํ™˜ํ•˜๋Š” ๊ธฐ์ˆ ๊ณผ ๋ฐ”์ดํŠธ๋กœ ๋ณ€ํ™˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ธฐ์ˆ (์—ญ์ง๋ ฌํ™”)๋ฅผ ํ†ต์นญํ•˜๋Š” ๋ง์„ ์˜๋ฏธํ•œ๋‹ค.
  • ๋™์ž‘ ์›๋ฆฌ๋ฅผ ๋งํ•˜์ž๋ฉด ๋Ÿฐํƒ€์ž„ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ(ํž™) ์— ์ƒ์ฃผํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”์ดํŠธ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ธฐ์ˆ ๊ณผ ๋ฐ”์ดํŠธ ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ด ๋Ÿฐํƒ€์ž„ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์— ์ƒ์ฃผ์‹œํ‚ค๋Š” ๊ธฐ์ˆ ์„ ์˜๋ฏธํ•œ๋‹ค.

์ฐธ๊ณ ) DB์˜ Serializable๊ณผ์˜ ์ฐจ์ด์ ์€? DB์˜ Serializable์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํŠธ๋žœ์žญ์…˜์ด ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•  ๋•Œ ํŠธ๋žœ์žญ์…˜์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋งˆ์น˜ ํ•˜๋‚˜์”ฉ ์ฒ˜๋ฆฌ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋‚˜์˜ค๋Š” ๊ฒฉ๋ฆฌ ์ˆ˜์ค€์„ ์˜๋ฏธํ•œ๋‹ค. ์ผ๋ ฌ๋กœ ํ•˜๋‚˜์”ฉ ์ฒ˜๋ฆฌ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋‚˜์˜ค๋Š” ํ˜„์ƒ์˜ ์˜๋ฏธ๊ฐ€ ํฌ๋‹ค. ๋‹จ์ ์€ ๋™์‹œ์— ์—ฌ๋Ÿฌ ํŠธ๋žœ์žญ์…˜์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์œผ๋‹ˆ ์„ฑ๋Šฅ ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์“ฐ๊ธฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

์ง๋ ฌํ™” ๋ฐฉ๋ฒ• : Serializable์„ ๊ตฌํ˜„ํ•˜๊ณ  ObjectOutputStream์„ ์‚ฌ์šฉํ•œ๋‹ค.

        /*
         * ์ž๋ฐ” ์ง๋ ฌํ™” : ObjectOutputStream์„ ์ด์šฉํ•œ๋‹ค
         */
        Account account = Account.of("jack", "010-7720-7954", 28);
        byte[] serializedAccount;

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
                oos.writeObject(account);
                serializedAccount = baos.toByteArray();

                // ๋ฐ”์ดํŠธ๋กœ ๋ณ€ํ™˜๋œ (์ง๋ ฌํ™”๋œ) ๊ฒฐ๊ณผ๋ฅผ String์œผ๋กœ ์ธ์ฝ”๋”ฉ                
                System.out.println(Base64.getEncoder().encodeToString(serializedAccount));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

์ง๋ ฌํ™” ๊ฒฐ๊ณผ

image

์—ญ์ง๋ ฌํ™” ๋ฐฉ๋ฒ•

์—ญ์ง๋ ฌํ™” ์กฐ๊ฑด

  • ์ง๋ ฌํ™” ๋Œ€์ƒ์ด ๋œ ๊ฐ์ฒด์˜ ํด๋ž˜์Šค๊ฐ€ ํด๋ž˜์Šค ํŒจ์Šค์— ์กด์žฌํ•ด์•ผ ํ•˜๋ฉฐ import ๋˜์–ด ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • ์ž๋ฐ” ์ง๋ ฌํ™” ๋Œ€์ƒ ๊ฐ์ฒด๋Š” ๋™์ผํ•œ serialVersionUID๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.
// seialVersionUID
private static final long serialVersionUID = 1L;
        /*
         * ์ž๋ฐ” ์—ญ์ง๋ ฌํ™” : ObjectInputStream์„ ์ด์šฉํ•œ๋‹ค.
         */
        try (ByteArrayInputStream bais = new ByteArrayInputStream(serializedAccount)) {
            try (ObjectInputStream ois = new ObjectInputStream(bais)) {
                Object objectAccount = ois.readObject();
                Account accountFromSerialized = (Account) objectAccount;
                System.out.println(accountFromSerialized);
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

์—ญ์ง๋ ฌํ™” ๊ฒฐ๊ณผ

image

์ž๋ฐ” ์ง๋ ฌํ™” ๋ฐฉ๋ฒ•์„ ์™œ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?

  • ์ง๋ ฌํ™” ๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•˜๋‹ค. ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ CSV, XML, JSON์œผ๋กœ ๋ฐ”๊พธ๋Š” ๋ฐฉ๋ฒ•๋„ ์ง๋ ฌํ™” ๋ฐฉ๋ฒ•์ด๋‹ค. ๊ทธ๋Ÿผ ๊ทธ๋ƒฅ JSON ํ˜•์‹์œผ๋กœ ์ง๋ ฌํ™”๋ฅผ ํ•ด์„œ ์‹œ์Šคํ…œ ๊ฐ„ ์†Œํ†ต์„ ํ•˜๋ฉด ๋ ํ…๋ฐ ์™œ ์ž๋ฐ” ์ง๋ ฌํ™” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ• ๊นŒ?

๋ฌผ๋ก  ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค. ๋ชฉ์ ์— ๋”ฐ๋ผ ์ž˜ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿผ ์ž๋ฐ” ์ง๋ ฌํ™”์˜ ์žฅ์ ์„ ์‚ดํŽด๋ณด์ž

์ž๋ฐ” ์ง๋ ฌํ™”์˜ ์žฅ์ 

  • ์ž๋ฐ” ์ง๋ ฌํ™”๋Š” ์ž๋ฐ” ์‹œ์Šคํ…œ์—์„œ ๊ฐœ๋ฐœ์— ์ตœ์ ํ™”๋˜์–ด ์žˆ๋‹ค. ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์˜ ํด๋ž˜์Šค๋ผ๋„ ์ง๋ ฌํ™”๊ฐ€ ์‰ฝ๊ฒŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

์ž๋ฐ” ์ง๋ ฌํ™”์˜ ๋‹จ์ 

  • ์—ญ์ง๋ ฌํ™” ์‹œ ๊ฐ์ฒด ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์ง๋ ฌํ™”๊ฐ€ ์‹คํŒจํ•  ์ˆ˜ ์žˆ๋‹ค. -> ์ง์ ‘ serialVersionUID ๊ฐ’์„ ๊ด€๋ฆฌํ•ด์ฃผ์–ด์•ผ ํด๋ž˜์Šค ๋ณ€๊ฒฝ ์‹œ ํ˜ผ๋ž€์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ serialVersionUID๊ฐ€ ์—†๋‹ค๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ ํด๋ž˜์Šค์˜ ๊ตฌ์กฐ์ •๋ณด๋กœ ํ•ด์‰ฌ๊ฐ’์ด ๋งŒ๋“ค์–ด์ ธ์„œ serialVersionUID๋กœ ์ง€์ •๋œ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ง€์ •ํ•˜์ง€ ์•Š๊ณ  ํด๋ž˜์Šค ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด serialVersionUID๊ฐ€ ๋ฐ”๋€๋‹ค.
  • ์ง์ ‘ serialVersionUID๋ฅผ ๊ด€๋ฆฌํ•˜๋”๋ผ๋„ ๊ฐ์ฒด ํ•„๋“œ์˜ ํƒ€์ž…์ด ๋ณ€๊ฒฝ๋˜๋ฉด ์—ญ์ง๋ ฌํ™”๊ฐ€ ์‹คํŒจํ•œ๋‹ค.

์ž๋ฐ” ์ง๋ ฌํ™”๊ฐ€ ์šฐ๋ฆฌ๋ž‘ ๋ฌด์Šจ ์ƒ๊ด€์ผ๊นŒ? (์ค‘์š”ํ•œ ๊ธฐ์ˆ ์ž„์—๋„ ์ž˜ ๋ชฐ๋ž๋˜ ์ด์œ ๋Š”?)

  • ๋Ÿฐํƒ€์ž„ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์—๋งŒ ์ƒ์ฃผํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ์˜์†ํ™”(Persistence)ํ•  ๋•Œ ํ•„์š”ํ•˜๋‹ค. ์‹œ์Šคํ…œ์ด ์ข…๋ฃŒ๋˜๋”๋ผ๋„ ์—†์–ด์ง€์ง€ ์•Š๋Š” ์žฅ์ ์ด ์žˆ๊ณ  ๋„คํŠธ์›Œํฌ๋กœ ์ฃผ๊ณ  ๋ฐ›์„ ์ˆ˜๋„ ์žˆ๋‹ค.
  • ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์Šคํ”„๋ง์—์„œ๋Š” ์ž๋ฐ” ์ง๋ ฌํ™”๋ฅผ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค. @RestController ์‚ฌ์šฉ ์‹œ ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ JSON ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š”๋ฐ ์ด ๋•Œ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ JSON์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ณผ์ •์—๋„ ์ง๋ ฌํ™”๊ฐ€ ์ผ์–ด๋‚œ๋‹ค. (์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต๋ถ€๊ฐ€ ํ•„์š”..)

@RestController๋Š” @Controller์™€ @ResponseBody๊ฐ€ ํ•ฉ์ณ์ ธ ์žˆ๋‹ค. @ResponseBody ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ์ฒด๊ฐ€ ์ž๋™์œผ๋กœ ์ง๋ ฌํ™”๋˜์–ด HttpResponse์— ๋‹ด๊ธด๋‹ค.

  • ์™ธ๋ถ€์— ์˜ค๋žœ ์‹œ๊ฐ„ ์ €์žฅํ•˜๋Š”(์˜์†ํ™”) ๋ฐ์ดํ„ฐ๋Š” ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ง๋ ฌํ™”๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๋Š”๊ฒŒ ์ข‹๋‹ค.

์ฐธ๊ณ 

์‹ฑ๊ธ€ํ„ด ์ง๋ ฌํ™”๋ฅผ ์œ„ํ•œ Transient์™€ readResolve() ๊ตฌํ˜„

Transient๋ž€

  • ํ•ด๋‹น ๋ฐ์ดํ„ฐ(๊ฐ์ฒด ๋“ฑ)์„ ์ง๋ ฌํ™”ํ•  ๋•Œ ์ œ์™ธํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ์„ ์–ธํ•˜๋Š” ํ‚ค์›Œ๋“œ์ด๋‹ค.
  • ํŒจ์Šค์›Œ๋“œ์™€ ๊ฐ™์€ ๋ณด์•ˆ์ •๋ณด๊ฐ€ ์ง๋ ฌํ™”๋˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Transient ์‹ค์Šต

  • name ํ•„๋“œ์— transient ์ถ”๊ฐ€
@Getter
public class Account implements Serializable {

    private transient String name;
    private String phoneNumber;
    private int age;
  • Account ๊ฐ์ฒด ์ง๋ ฌํ™” ๋ฐ ์—ญ์ง๋ ฌํ™” ์ง„ํ–‰
public static void main(String[] args) {

        /*
         * ์ž๋ฐ” ์ง๋ ฌํ™” : ObjectOutputStream์„ ์ด์šฉํ•œ๋‹ค
         */
        Account account = Account.of("jack", "010-7720-7954", 28);
        byte[] serializedAccount = new byte[1000];

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
                oos.writeObject(account);
                serializedAccount = baos.toByteArray();

                // ๋ฐ”์ดํŠธ๋กœ ๋ณ€ํ™˜๋œ (์ง๋ ฌํ™”๋œ) ๊ฒฐ๊ณผ๋ฅผ String์œผ๋กœ ์ธ์ฝ”๋”ฉ
                System.out.println(Base64.getEncoder().encodeToString(serializedAccount));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        /*
         * ์ž๋ฐ” ์—ญ์ง๋ ฌํ™” : ObjectInputStream์„ ์ด์šฉํ•œ๋‹ค.
         */
        try (ByteArrayInputStream bais = new ByteArrayInputStream(serializedAccount)) {
            try (ObjectInputStream ois = new ObjectInputStream(bais)) {
                Object objectAccount = ois.readObject();
                Account accountFromSerialized = (Account) objectAccount;
                System.out.println(accountFromSerialized);
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

์—ญ์ง๋ ฌํ™” ๊ฒฐ๊ณผ

  • transient ํ•„๋“œ๊ฐ€ null๋กœ ์—ญ์ง๋ ฌํ™”๋œ๋‹ค.

image

readResolve()

  • ์‹ฑ๊ธ€ํ„ด์œผ๋กœ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด๋ฅผ ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ๋งŒ์•ฝ readResolve()๋ฅผ ์‹ฑ๊ธ€ํ„ด ๊ฐ์ฒด์— ๊ตฌํ˜„ํ•˜์ง€ ์•Š์œผ๋ฉด ์‹ฑ๊ธ€ํ„ด์ด๋ผ๋„ ์—ญ์ง๋ ฌํ™”ํ•  ๋•Œ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.

readResolve() ์‹ค์Šต

  • ์‹ฑ๊ธ€ํ„ด ๊ฐ์ฒด ์ƒ์„ฑ
public class JackSingleton implements Serializable {
    private static final JackSingleton INSTANCE = new JackSingleton();

    public JackSingleton() {
    }
    
    public static JackSingleton getInstance() {
        return INSTANCE;
    }
}
  • Serializer ํด๋ž˜์Šค ๊ตฌํ˜„
package com.titanic.javatest.serializable;

import java.io.*;
import java.util.Base64;

public class Serializer {

    public String serialize(Object object) {
        /*
         * ์ž๋ฐ” ์ง๋ ฌํ™” : ObjectOutputStream์„ ์ด์šฉํ•œ๋‹ค
         */
        byte[] serialized;

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
                oos.writeObject(object);
                serialized = baos.toByteArray();

                // ๋ฐ”์ดํŠธ๋กœ ๋ณ€ํ™˜๋œ (์ง๋ ฌํ™”๋œ) ๊ฒฐ๊ณผ๋ฅผ String์œผ๋กœ ์ธ์ฝ”๋”ฉ
                return Base64.getEncoder().encodeToString(serialized);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    public Object deserialize(String serialized) {
        /*
         * ์ž๋ฐ” ์—ญ์ง๋ ฌํ™” : ObjectInputStream์„ ์ด์šฉํ•œ๋‹ค.
         */
        byte[] serializedSingleton = Base64.getDecoder().decode(serialized);
        try (ByteArrayInputStream bais = new ByteArrayInputStream(serializedSingleton)) {
            try (ObjectInputStream ois = new ObjectInputStream(bais)) {
                Object objectAccount = ois.readObject();
                return objectAccount;
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

}
  • readResolveTest ๊ตฌํ˜„
package com.titanic.javatest.serializable;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class readResolveTest {

    private JackSingleton jackSingleton;
    private Serializer serializer;

    @BeforeEach
    void setUp() {
        this.jackSingleton = JackSingleton.getInstance();
        this.serializer = new Serializer();
    }

    @Test
    void ์ผ๋ฐ˜์ง๋ ฌํ™”๋ฅผ_ํ…Œ์ŠคํŠธํ•œ๋‹ค() throws Exception {
        // when
        String serialized = serializer.serialize(jackSingleton);
        JackSingleton deserialized = (JackSingleton) serializer.deserialize(serialized);

        // then
        assertThat(deserialized).isSameAs(jackSingleton);
        assertThat(deserialized).isEqualTo(jackSingleton);
    }

    @Test
    void readResolve๋ฅผ_ํ…Œ์ŠคํŠธํ•œ๋‹ค() throws Exception {
        // when
        String serialized = serializer.serialize(jackSingleton);
        JackSingleton deserialized = (JackSingleton) serializer.deserialize(serialized);

        // then
        assertThat(deserialized).isSameAs(jackSingleton);
        assertThat(deserialized).isEqualTo(jackSingleton);
    }
}
  • readResove() ๊ตฌํ˜„ํ•œ ์‹ฑ๊ธ€ํ†ค ๊ฐ์ฒด
package com.titanic.javatest.serializable;

import java.io.Serializable;

public class JackSingleton implements Serializable {
    private static final JackSingleton INSTANCE = new JackSingleton();

    public JackSingleton() {
    }

    public static JackSingleton getInstance() {
        return INSTANCE;
    }

    private Object readResolve() {
        return INSTANCE;
    }
}

readResolve()๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๋Š” ๊ฒฐ๊ณผ

  • ์‹ฑ๊ธ€ํ„ด ๊ฐ์ฒด๋ฅผ ์—ญ์ง๋ ฌํ™”ํ•˜๋ฉด ์‹ฑ๊ธ€ํ„ด ์ธ์Šคํ„ด์Šค์™€ ๋‹ค๋ฅด๋‹ค๊ณ  ๋‚˜์˜จ๋‹ค. image

  • readResolve()๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒฐ๊ณผ : ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•œ๋‹ค image

์ฐธ๊ณ 

๋ฆฌํ”Œ๋ž™์…˜ (Reflection)

  • ๋ฆฌํ”Œ๋ž™์…˜์€ ์ž๋ฐ” ์–ธ์–ด๊ฐ€ ๊ฐ€์ง„ ํŠน์ง•์ด๋‹ค. ๋ฆฌํ”Œ๋ž™์…˜์€ ์ž๋ฐ” ํ”„๋กœ๊ทธ๋žจ์ด ์ž๊ธฐ ์ž์‹ (๊ฐ์ฒด)์ด๋‚˜ ํ”„๋กœ๊ทธ๋žจ ๋‚ด ์†์„ฑ์„ ์กฐ์‚ฌ,๋ถ„์„ํ•˜๋Š”๋ฐ ๋„์™€์ฃผ๋Š” ๊ธฐ์ˆ ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ž๋ฐ” ํด๋ž˜์Šค๊ฐ€ ํด๋ž˜์Šค ๋‚ด ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ •๋ณด์™€ ํ•ด๋‹น ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ display(ํ‘œํ˜„?)ํ•˜๊ฒŒ ๋„์™€์ค€๋‹ค.
  • ์‹ค์šฉ์ ์ธ ๋‚ด์šฉ์œผ๋กœ๋Š” ์ด๋ฏธ ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋œ ํด๋ž˜์Šค์—์„œ ๋˜ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ๋™์ ์œผ๋กœ ๋กœ๋”ฉ(Dynamic Loading)ํ•˜์—ฌ ์ƒ์„ฑ์ž, ๋ฉค๋ฒ„ ํ•„๋“œ, ๋ฉค๋ฒ„ ๋ฉ”์„œ๋“œ ๋“ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ค€๋‹ค.
  • ๋ฐ˜์‚ฌ, ํˆฌ์˜์ด๋ผ๋Š” ์‚ฌ์ „์ ์ธ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ ๊ฐ์ฒด(์ธ์Šคํ„ด์Šค)๋ฅผ ํ†ตํ•ด ํด๋ž˜์Šค์˜ ์ •๋ณด๋ฅผ ๋ถ„์„ํ•ด ๋‚ด๋Š” ํ”„๋กœ๊ทธ๋žจ ๊ธฐ๋ฒ•์„ ์˜๋ฏธํ•œ๋‹ค.

์™œ ์‚ฌ์šฉํ• ๊นŒ?

  • ๋™์ ๋กœ๋”ฉ์— ๋Œ€ํ•œ ๊ธฐ์ˆ ์„ ์ง€์›ํ•˜๋‹ˆ ์ž๋ฐ” ํ”„๋กœ๊ทธ๋žจ์„ ์œ ์—ฐํ•˜๊ฒŒ ์šด์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. (๋‹คํ˜•์„ฑ ๋“ฑ)

์ฃผ์˜ํ•  ์ 

  • ์™ธ๋ถ€์— ๊ณต๊ฐœ๋˜์ง€ ์•Š๋Š” private ๋ฉค๋ฒ„๋„ ์ ‘๊ทผ๊ณผ ์กฐ์ž‘๋„ ๊ฐ€๋Šฅํ•˜๋‹ˆ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. private ๋ฉค๋ฒ„๋Š” Field.setAccessible() ๋ฉ”์„œ๋“œ๋ฅผ true๋กœ ์ง€์ •ํ•˜๋ฉด ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.

์ฐธ๊ณ 

์งˆ๋ฌธ

1. ์‹ฑ๊ธ€ํ„ด์ธ์ง€ ์•„๋‹Œ์ง€ ์–ด๋–ป๊ฒŒ ํŒ๋‹จํ•˜๋Š”์ง€?

  • ๋ฐ˜ํ™˜ํ•˜๋Š” ์ธ์Šคํ„ด์Šค์˜ ์ฃผ์†Œ๊ฐ€ ๊ฐ™์€์ง€ ๋‹ค๋ฅธ์ง€ ํŒŒ์•…ํ•˜๋ฉด ๋œ๋‹ค.
  • ์Šคํ”„๋ง์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ๋นˆ์„ ์‹ฑ๊ธ€ํ„ด์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค.

2. getInstance()๋กœ ๊ตฌํ˜„ํ•œ ์‹ฑ๊ธ€ํ„ด์˜ ์žฅ์ ์€ ์–ธ์ œ๋“  ์‹ฑ๊ธ€ํ„ด์ด ์•„๋‹Œ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ์˜๋ฏธ๋Š”?

  • public static ์ƒ์ˆ˜๋กœ ๊ตฌํ˜„ํ•œ ์‹ฑ๊ธ€ํ„ด์€ ์‹ฑ๊ธ€ํ„ด ์ธ์Šคํ„ด์Šค ์™ธ์— ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ”๊ฟ€ ๋ฐฉ๋ฒ•์ด ์—†์ง€๋งŒ getInstance()๋Š” ๋ฐ˜ํ™˜ํƒ€์ž…์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. ์ด์œ ๋Š” ๋ฉ”์„œ๋“œ๋กœ ๊ตฌํ˜„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋กœ์ง์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

3. ์™œ ์ง๋ ฌํ™”, ์—ญ์ง๋ ฌํ™”๋ฅผ ์‚ฌ์šฉํ• ๊นŒ?

  • ์œ„ ์ž๋ฐ”์˜ Serializable ๋‚ด์šฉ์— ์ž์„ธํžˆ ๊ธฐ๋ก๋˜์–ด ์žˆ์Œ.
  • ๊ฐ™์€ Java ์‹œ์Šคํ…œ ๊ฐ„์— ๊ฐ€์žฅ ์‰ฝ๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์‹
  • ์–ธ์ œ ์‚ฌ์šฉํ• ๊นŒ?
    • DB์— ์˜์†ํ™” ํ•  ๋•Œ, ์ด๋–„ byteStream์œผ๋กœ ๋ฐ”๊ฟ”์„œ ๋“ค์–ด๊ฐ
    • byteStream -> ์ง๋ ฌํ™”(์ข€ ๋” ๋ณต์žกํ•œ ๋ฐฉ์‹์ด ์žˆ์Œ) -> DB

4. p.24 public ํ•„๋“œ ๋ฐฉ์‹์˜ ํฐ ์žฅ์ ์€ ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ์‹ฑ๊ธ€ํ„ด์ž„์ด API์— ๋ช…๋ฐฑํžˆ ๋“œ๋Ÿฌ๋‚œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.์˜ ์˜๋ฏธ๋Š”?

  • public ํ•„๋“œ ๋ฐฉ์‹์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•˜์ง€ ์•Š๊ณ  .(dot) ์—ฐ์‚ฐ์ž๋กœ ๋ฐ”๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋‹ˆ ๋‹ค๋ฅธ ๋กœ์ง์ด ์ถ”๊ฐ€๋˜์ง€ ์•Š๊ณ  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.