๊ด€๋ฆฌ ๋ฉ”๋‰ด

<Hello Hosung๐Ÿ˜Ž/>

[Java] ์ง๋ ฌํ™”(Serialization)๋ž€? ๋ณธ๋ฌธ

๐Ÿ’ป Java/ใ…คJava(Basic)

[Java] ์ง๋ ฌํ™”(Serialization)๋ž€?

์ขŒ์ถฉ์šฐ๋Œ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ผ๊ธฐ๐Ÿง 2024. 11. 12. 14:25

Java์—์„œ **์ง๋ ฌํ™”(Serialization)**๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ํŒŒ์ผ์— ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์ „์†กํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“œ๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. ๋ฐ˜๋Œ€๋กœ, ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์„ ๋‹ค์‹œ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ณผ์ •์„ **์—ญ์ง๋ ฌํ™”(Deserialization)**๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
 
์ง๋ ฌํ™”๋Š” ์ฃผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์˜์†ํ™”ํ•˜๊ฑฐ๋‚˜ ์›๊ฒฉ ํ†ต์‹ ์—์„œ ๊ฐ์ฒด๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๊ฐ„์— ๊ฐ์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ๋•Œ ์ง๋ ฌํ™”๊ฐ€ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
์ด ๋ธ”๋กœ๊ทธ์—์„œ๋Š” Java์—์„œ ์ง๋ ฌํ™”๊ฐ€ ๋ฌด์—‡์ธ์ง€, ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์˜ˆ์ œ ์ฝ”๋“œ๋กœ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
 
 

1. ์ง๋ ฌํ™”์˜ ๊ธฐ๋ณธ ๊ฐœ๋…

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

์ง๋ ฌํ™” ์‚ฌ์šฉ ์˜ˆ์‹œ

  • ํŒŒ์ผ ์ €์žฅ: ๊ฐ์ฒด๋ฅผ ํŒŒ์ผ์— ์ €์žฅํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•œ ํ›„์—๋„ ๋‹ค์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋„คํŠธ์›Œํฌ ํ†ต์‹ : ๊ฐ์ฒด๋ฅผ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ ์ปดํ“จํ„ฐ๋กœ ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„ธ์…˜ ๊ด€๋ฆฌ: ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉ์ž ์„ธ์…˜ ์ •๋ณด๋ฅผ ๊ฐ์ฒด๋กœ ์ €์žฅํ•˜๊ณ  ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

2. Java์—์„œ ์ง๋ ฌํ™” ์‚ฌ์šฉ๋ฒ•

Java์—์„œ๋Š” java.io.Serializable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง๋ ฌํ™”๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” marker interface๋กœ, ์ด๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋Š” ์ง๋ ฌํ™”๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

Serializable ์ธํ„ฐํŽ˜์ด์Šค

Serializable ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์œผ๋ฉฐ, ๋‹จ์ˆœํžˆ ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ์ง๋ ฌํ™”๋  ์ˆ˜ ์žˆ์Œ์„ JVM์—๊ฒŒ ์•Œ๋ฆฌ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

import java.io.Serializable;

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

    // ์ƒ์„ฑ์ž
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getter/Setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

 

3. ์ง๋ ฌํ™” ์˜ˆ์ œ

์ง๋ ฌํ™”๋Š” ObjectOutputStream ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ์—ญ์ง๋ ฌํ™”๋Š” ObjectInputStream ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
 
์ง๋ ฌํ™” ์˜ˆ์ œ

import java.io.*;

public class SerializationExample {

    public static void main(String[] args) {
        // ์ง๋ ฌํ™”ํ•  ๊ฐ์ฒด ์ƒ์„ฑ
        Person person = new Person("Alice", 30);

        try {
            // ๊ฐ์ฒด๋ฅผ ํŒŒ์ผ๋กœ ์ง๋ ฌํ™”
            FileOutputStream fileOut = new FileOutputStream("person.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);

            out.writeObject(person);
            out.close();
            fileOut.close();
            System.out.println("๊ฐ์ฒด๊ฐ€ person.ser ํŒŒ์ผ์— ์ง๋ ฌํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
        } catch (IOException i) {
            i.printStackTrace();
        }
    }
}

 
์œ„ ์ฝ”๋“œ์—์„œ๋Š” Person ๊ฐ์ฒด๋ฅผ person.ser๋ผ๋Š” ํŒŒ์ผ๋กœ ์ง๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค. ObjectOutputStream์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ์ด๋ฅผ ํŒŒ์ผ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
 
์—ญ์ง๋ ฌํ™” ์˜ˆ์ œ

import java.io.*;

public class DeserializationExample {

    public static void main(String[] args) {
        Person person = null;

        try {
            // ์ง๋ ฌํ™”๋œ ํŒŒ์ผ์„ ์ฝ์–ด ๊ฐ์ฒด๋กœ ์—ญ์ง๋ ฌํ™”
            FileInputStream fileIn = new FileInputStream("person.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);

            person = (Person) in.readObject();
            in.close();
            fileIn.close();

            System.out.println("์—ญ์ง๋ ฌํ™”๋œ ๊ฐ์ฒด: " + person.getName() + ", " + person.getAge());
        } catch (IOException | ClassNotFoundException i) {
            i.printStackTrace();
        }
    }
}

 
์œ„ ์ฝ”๋“œ์—์„œ๋Š” person.ser ํŒŒ์ผ์—์„œ ๊ฐ์ฒด๋ฅผ ์ฝ์–ด์™€ Person ๊ฐ์ฒด๋กœ ์—ญ์ง๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค. ObjectInputStream์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์„ ์ฝ๊ณ  ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
 

4. ์ง๋ ฌํ™”์˜ ์œ ์˜์‚ฌํ•ญ

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

private static final long serialVersionUID = 1L;

 
transient ํ‚ค์›Œ๋“œ
์ง๋ ฌํ™”์—์„œ ์ œ์™ธํ•˜๊ณ  ์‹ถ์€ ํ•„๋“œ๋Š” transient ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง๋ ฌํ™” ๋Œ€์ƒ์—์„œ ์ œ์™ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ณด์•ˆ์ƒ ์ €์žฅํ•˜์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๋‚˜ ์„ธ์…˜ ์ •๋ณด ๊ฐ™์€ ๋ฐ์ดํ„ฐ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

private transient String password;

 
์ •์  ๋ณ€์ˆ˜
ํด๋ž˜์Šค์˜ ์ •์  ๋ณ€์ˆ˜(static ๋ณ€์ˆ˜)๋Š” ์ง๋ ฌํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์ •์  ๋ณ€์ˆ˜๋Š” ํด๋ž˜์Šค ๋กœ๋”ฉ ์‹œ์ ์— ๋ฉ”๋ชจ๋ฆฌ์— ๋กœ๋“œ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ง๋ ฌํ™”์˜ ๋Œ€์ƒ์ด ์•„๋‹ˆ๋ผ๋Š” ํŠน์ง•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
 
์ƒ์† ๊ด€๊ณ„์—์„œ์˜ ์ง๋ ฌํ™”
์ƒ์† ๊ด€๊ณ„์— ์žˆ๋Š” ํด๋ž˜์Šค์—์„œ ๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ Serializable์„ ๊ตฌํ˜„ํ•˜๊ณ , ์ž์‹ ํด๋ž˜์Šค์—์„œ ์ด๋ฅผ ์ƒ์†๋ฐ›์„ ๊ฒฝ์šฐ, ์ž์‹ ํด๋ž˜์Šค๋„ ์ž๋™์œผ๋กœ ์ง๋ ฌํ™”๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ž์‹ ํด๋ž˜์Šค์—์„œ ์ง๋ ฌํ™”๊ฐ€ ํ•„์š”ํ•œ ํ•„๋“œ๋ฅผ transient๋กœ ์ง€์ •ํ–ˆ๋‹ค๋ฉด ํ•ด๋‹น ํ•„๋“œ๋Š” ์ง๋ ฌํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
 

5. ์ง๋ ฌํ™”์™€ ์„ฑ๋Šฅ

์ง๋ ฌํ™”์™€ ์—ญ์ง๋ ฌํ™”๋Š” ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋Œ€์šฉ๋Ÿ‰ ๊ฐ์ฒด๋‚˜ ๋ณต์žกํ•œ ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํ™”ํ•˜๊ณ  ์ „์†กํ•˜๋Š” ๊ฒฝ์šฐ, ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ObjectInputStream๊ณผ ObjectOutputStream ๋Œ€์‹ , JSON, XML, Protocol Buffers, Avro์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ํฌ๋งท์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
 

๋งˆ๋ฌด๋ฆฌ

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