JAVA

[Java] ์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ” ์ง๋ ฌํ™”

YeopJu 2024. 7. 16. 17:54
๋ฐ˜์‘ํ˜•

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์ž๋ฐ” ์ง๋ ฌํ™”์— ๋Œ€ํ•ด ์จ๋ณด๊ณ ์ž ํ•œ๋‹ค. ํ˜„๋Œ€ ๋ฐฑ์—”๋“œ ์‹œ์Šคํ…œ์—์„œ๋Š” ์•„๋ž˜์—์„œ ์„ค๋ช…ํ•  ๋‹ค์–‘ํ•œ ์ด์œ ๋“ค๋กœ ์ธํ•ด ์ž๋ฐ”์˜ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ์ง๋ ฌํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋“œ๋ฌธ ๊ฒƒ์ด ์‚ฌ์‹ค์ด๋‹ค. ๊ทธ ๋Œ€์‹  JSON, XML. Avro์™€ ๊ฐ™์€ ์ง๋ ฌํ™” ํฌ๋งท์„ ๋งŽ์ด ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ธ€์„ ์“ธ๊นŒ์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์„ ํ–ˆ์ง€๋งŒ ์ž๋ฐ”์˜ ๋งŽ์€ ํด๋ž˜์Šค๋“ค์ด ์ง๋ ฌํ™”๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๊ธฐ๋„ ํ•˜๊ณ , ์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”์—์„œ ์ฝ์€ ๋‚ด์šฉ์„ ๊ธฐ์–ตํ•ด๋‘๊ธฐ ์œ„ํ•ด ๊ธ€์„ ์“ฐ๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค.

 


 

โ˜‘๏ธ ์ง๋ ฌํ™”

์ง๋ ฌํ™”๋ž€ JVM์˜ ํž™ ๋˜๋Š” ์Šคํƒ ์˜์—ญ ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ๋Š” ๊ฐ์ฒด ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฅธ ์ปดํ“จํ„ฐ์˜ JVM์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. ๋‹ค๋ฅธ ์ปดํ“จํ„ฐ์˜ JVM์—์„œ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์—ญ์ง๋ ฌํ™”๋ฅผ ํ†ตํ•ด ์ž๋ฐ” ๊ฐ์ฒด๋กœ ๋‹ค์‹œ ๋ณ€ํ™˜์‹œ์ผœ ์‚ฌ์šฉํ•œ๋‹ค.

 

์ง๋ ฌํ™”๋Š” Serializable์ด๋ผ๋Š” ์ž๋ฐ”์˜ ๋งˆ์ปค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ Implements ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋•Œ ์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™”์—๋Š” ๊ฐ๊ฐ ObjectOutputStream์™€ ObjectInputStream์ด ์‚ฌ์šฉ๋˜๋ฉฐ ์ง๋ ฌํ™”๋  ๋•Œ๋Š” ์˜ค์ง ๊ฐ์ฒด์˜ ํ•„๋“œ๊ฐ’ ๋งŒ์„ ์ €์žฅํ•œ๋‹ค.

 

์ง๋ ฌํ™” ์กฐ์ž‘

๊ฐ์ฒด์˜ ์ง๋ ฌํ™”๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

๋จผ์ € transient ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • ํ•„๋“œ๊ฐ’์„ ์ง๋ ฌํ™” ๋Œ€์ƒ์—์„œ ์ œ์™ธ ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ์ด ๋•Œ transient ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์€ ํ•„๋“œ ๊ฐ’์€ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ง๋ ฌํ™”๋˜๊ธฐ ๋•Œ๋ฌธ์— Primitive ํƒ€์ž…์€ ๊ฐ ํƒ€์ž…์˜ ๋””ํดํŠธ ๊ฐ’, Reference ํƒ€์ž…์€ null๋กœ ์ง๋ ฌํ™” ๋œ๋‹ค.

 

๋‘๋ฒˆ์งธ ๋ฐฉ๋ฒ•์€, readObject์™€ writeObject๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ง๋ ฌํ™”, ์—ญ์ง๋ ฌํ™” ๊ณผ์ •์—์„œ ๊ฒ€์ฆ ๋กœ์ง ๋˜๋Š” ์กฐ๊ฑด๋ถ€ ๋กœ์ง์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

class Player implements Serializable {
    String name;
    String password;
    int age;

    public Customer(String name, String password, int age) {
        this.name = name;
        this.password = password;
        this.age = age;
    }

    private void writeObject(ObjectOutputStream out) throws IOException{
        out.writeObject(name);
        out.writeInt(age);
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
        this.name = (String) in.readObject();
        this.age = in.readInt();
    }
}

 

๊ฐ์ฒด ์ƒ์† ๊ด€๊ณ„์—์„œ ์ง๋ ฌํ™”

๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ Serializable์„ Implements ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์ž์‹ ํด๋ž˜์Šค๋Š” Implements ํ•˜์ง€ ์•Š์•„๋„ ์ง๋ ฌํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ ์ž์‹ ํด๋ž˜์Šค์—์„œ๋งŒ Serializable์„ ๊ตฌํ˜„ํ–ˆ๋‹ค๋ฉด ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ํ•„๋“œ๋Š” ๋ฌด์‹œ๋˜๊ณ  ์ž์‹ ํด๋ž˜์Šค์˜ ํ•„๋“œ๋งŒ ์ง๋ ฌํ™”๋œ๋‹ค.

 

 

์ง๋ ฌํ™” ๋ฒ„์ „ ๊ด€๋ฆฌ

์ง๋ ฌํ™”๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋Š” serialVersionUID๋ผ๋Š” ๊ณ ์œ  ์‹๋ณ„๋ฒˆํ˜ธ๋ฅผ ๋ถ€์—ฌ ๋ฐ›์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ์ง๋ ฌํ™”, ์—ญ์ง๋ ฌํ™” ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•œ๋‹ค. ์ด๋Š” ์ˆ˜๋™์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์„ค์ •ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ, ๋Ÿฐํƒ€์ž„์— ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•œ ํ•ด์‹œํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค. 

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

ํ•˜์ง€๋งŒ ํ•„๋“œ ๊ฐ’์˜ ์ถ”๊ฐ€, ์‚ญ์ œ, ๋ณ€์ˆ˜ ์ด๋ฆ„ ๋ณ€๊ฒฝ, ์ œ์–ด์ž ๋ณ€๊ฒฝ์ด ์•„๋‹Œ ํ•„๋“œ ๊ฐ’์˜ ํƒ€์ž…์ด ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด ํด๋ž˜์Šค ๋ฒ„์ „์ด ๊ฐ™๋”๋ผ๋„ incompatible type ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ์ฃผ์˜ ์‚ฌํ•ญ์ด ์žˆ๋‹ค.

class Player implements Serializable {
    // private static final long์œผ๋กœ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค.
    private static final long serialVersionUID = 123L;
    
    private String name;
    private int age;
}

 

 

์ง๋ ฌํ™”๊ฐ€ ์œ„ํ—˜ํ•œ ์ด์œ 

์ง๋ ฌํ™”์˜ ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๋Š” ๊ณต๊ฒฉ ๋ฒ”์œ„๊ฐ€ ๋„ˆ๋ฌด ๋„“๊ณ  ์ง€์†์ ์œผ๋กœ ๋” ๋„“์–ด์ ธ ๋ฐฉ์–ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ์ ์ด๋‹ค.์ง๋ ฌํ™”๋ฅผ ํ•œ ํ›„, ์—ญ์ง๋ ฌํ™”๋ฅผ ํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋œ๋‹ค.

  • ๊ฐ์ฒด๋ฅผ ์ฝ๋Š” readObject ๋ฉ”์„œ๋“œ๋Š” ํด๋ž˜์Šค ํŒจ์Šค์— ์กด์žฌํ•˜๋Š” ์ง๋ ฌํ™”๋œ ๊ฑฐ์˜ ๋ชจ๋“  ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์„ ์—ญ์ง๋ ฌํ™”ํ•˜๋Š” ๊ณผ์ •์—์„œ ํ•ด๋‹น ํƒ€์ž… ์•ˆ์˜ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ์ฒด๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ๋œ๋‹ค. โžก๏ธ ์ „์ฒด๊ฐ€ ๊ณต๊ฒฉ ๋ฒ”์œ„์— ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.
  • ๋‹ค๋ฅธ ํฌ๋งท์— ๋น„ํ•ด์„œ ๋ช‡ ๋ฐฐ ์ด์ƒ์˜ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง„๋‹ค.
  • ์—ญ์ง๋ ฌํ™” ํญํƒ„์„ ๋งž์„ ์ˆ˜๋„ ์žˆ๋‹ค.
  • ์ง๋ ฌํ™”๋ฅผ ํ•˜๋ฉด ๋ฆด๋ฆฌ์ฆˆ ํ›„ ์ˆ˜์ •ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค.
  • ์ง๋ ฌํ™˜๋œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ๋„ ํ•˜๋‚˜์˜ API๊ฐ€ ๋˜์–ด ์ง€์†์ ์œผ๋กœ ์ง€์›ํ•ด์•ผํ•œ๋‹ค โžก๏ธ Private ํ•„๋“œ๋“ค์ด ๋…ธ์ถœ๋˜์–ด ์บก์Аํ™”๊ฐ€ ๊นจ์ง„๋‹ค.
  • ์ง๋ ฌํ™” ํด๋ž˜์Šค๊ฐ€ ์ˆ˜์ •๋˜๋ฉด ์‹ ๋ฒ„์ „์„ ์ง๋ ฌํ™” ํ•œ ํ›„ ๊ตฌ๋ฒ„์ „์œผ๋กœ ์—ญ์ง๋ ฌํ™” ํ•  ์ˆ˜ ์žˆ๋Š”์ง€, ๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ๋„ ๊ฐ€๋Šฅํ•œ์ง€ ํ…Œ์ŠคํŠธ ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ์–‘์ด ๋Š˜์–ด๋‚œ๋‹ค.

 

 

์ง๋ ฌํ™” ์œ„ํ—˜ ํšŒํ”ผ ๋ฐฉ๋ฒ•

  • ์ง๋ ฌํ™” ์œ„ํ—˜์„ ํšŒํ”ผํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์•„๋ฌด๊ฒƒ๋„ ์—ญ์ง๋ ฌํ™”ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค.
  • ๋ ˆ๊ฑฐ์‹œ ์‹œ์Šคํ…œ ๋•Œ๋ฌธ์— ์ง๋ ฌํ™”๋ฅผ ๋ฐฐ์ œํ•  ์ˆ˜ ์—†์„๋•Œ์—๋Š” ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ๋ฐ์ดํ„ฐ๋Š” ์ ˆ๋Œ€ ์—ญ์ง๋ ฌํ™”ํ•˜์ง€ ๋ง์ž.
  • ์—ญ์ง๋ ฌํ™” ๋ฐฉ์–ด ๊ธฐ๋ฒ•
  • readObject ๋ฉ”์„œ๋“œ๋Š” ์‚ฌ์‹ค์ƒ ๋˜ ๋‹ค๋ฅธ ์ƒ์„ฑ์ž์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฉ์–ด์ ์œผ๋กœ ์ž‘์„ฑํ•ด์•ผํ•œ๋‹ค.
/**๋ฐฉ์–ด์  ๋ณต์‚ฌ์™€ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” readObject ๋ฉ”์„œ๋“œ**/

private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
    s.defaultReadObject();
    // ๊ฐ€๋ณ€ ์š”์†Œ๋“ค์„ ๋ฐฉ์–ด์ ์œผ๋กœ ๋ณต์‚ฌํ•œ๋‹ค.
    start = new Date(start.getTime());
    end = new Date(end.getTime());

    // ๋ถˆ๋ณ€์‹์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•œ๋‹ค.
    if (start.compareto(end) > 0) {
        throw new InvalidObjectException(start + " after " + end);
    }
}
  • ์ธ์Šคํ„ด์Šค ์ˆ˜๋ฅผ ํ†ต์ œํ•ด์•ผํ•œ๋‹ค๋ฉด readResolve๊ฐ€ ์•„๋‹Œ Enum์„ ์‚ฌ์šฉํ•˜์ž.
    • readResolve๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด readObject๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ readResolve๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ , readResolve๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ๊ฐ์ฒด๊ฐ€ ์ƒˆ๋กœ์šด ๊ฐ์ฒด ๋Œ€์‹ ์— ๋ฐ˜ํ™˜๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ ์ƒ์„ฑํ•ด๋†“์€ ์‹ฑ๊ธ€ํ†ค ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๋งŒ์•ฝ ์—ด๊ฑฐ ํƒ€์ž…์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด ์„ ์–ธํ•œ ์ƒ์ˆ˜ ์™ธ์˜ ๋‹ค๋ฅธ ๊ฐ์ฒด๋Š” ์กด์žฌํ•˜์ง€ ์•Š์Œ์„ ์ž๋ฐ”๊ฐ€ ๋ณด์žฅํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ๊ถŒ์žฅํ•œ๋‹ค.  

 

 

๋ฐ˜์‘ํ˜•