๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๋นˆ ๊ตฌ๋ฉ ์ฑ„์šฐ๊ธฐ

[Java] ์–•์€ ๋ณต์‚ฌ Shallow Copy & ๊นŠ์€ ๋ณต์‚ฌ Deep Copy

์ถœ์ฒ˜

ChatGPT


์–•์€ ๋ณต์‚ฌ Shallow Copy

์ •์˜

์–•์€ ๋ณต์‚ฌ๋Š” ๊ฐ์ฒด์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ๋งŒ ๋ณต์‚ฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ฆ‰, ๊ฐ์ฒด ์ž์ฒด๋Š” ์ƒˆ๋กœ ์ƒ์„ฑ๋˜์ง€๋งŒ, ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค์€ ๋ณต์‚ฌํ•˜์ง€ ์•Š๊ณ  ์›๋ณธ ๊ฐ์ฒด์™€ ๊ฐ™์€ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•œ๋‹ค. -> ์ฐธ์กฐ๋งŒ ๋ณต์‚ฌ๋œ๋‹ค. ๋ณต์‚ฌ๋ณธ์„ ์ˆ˜์ •ํ•˜๋ฉด ์›๋ณธ๋„ ์ˆ˜์ •๋œ๋‹ค.

๋ฐฉ๋ฒ•

์ž๋ฐ”์—์„œ๋Š” Object ํด๋ž˜์Šค์˜ clone() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–•์€ ๋ณต์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. clone() ๋ฉ”์„œ๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ์ฒด์˜ ํ•„๋“œ ๊ฐ’์„ ๋ณต์‚ฌํ•˜์ง€๋งŒ, ์ฐธ์กฐ ํƒ€์ž…์˜ ํ•„๋“œ๋Š” ์ฐธ์กฐ๋งŒ ๋ณต์‚ฌํ•˜๋ฏ€๋กœ ์‹ค์ œ ๊ฐ์ฒด๋Š” ๋ณต์‚ฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

์˜ˆ์ œ

class Address {
    private String city;
    private String street;

    public Address(String city, String street) {
        this.city = city;
        this.street = street;
    }

    // Getters and Setters
}

class Person implements Cloneable {
    private String name;
    private int age;
    private Address address;

    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // ์–•์€ ๋ณต์‚ฌ
    }

    // Getters and Setters
}

 

์‚ฌ์šฉ ์˜ˆ

์–•์€ ๋ณต์‚ฌ๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ„๋‹จํžˆ ๋ณต์‚ฌํ•˜๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐ์ฒด์˜ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ๋งŒ ๋ณต์‚ฌํ•˜๊ณ  ๋‚ด๋ถ€์˜ ๊ฐ์ฒด๋“ค์€ ๊ณต์œ ํ•ด๋„ ์ƒ๊ด€์—†๋Š” ๊ฒฝ์šฐ์— ์ ํ•ฉํ•˜๋‹ค.

์ƒํ™ฉ

  • Configuration ๊ฐ์ฒด ๋ณต์‚ฌ: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ค์ •(configuration) ๊ฐ์ฒด๋ฅผ ๋ณต์‚ฌํ•  ๋•Œ ์–•์€ ๋ณต์‚ฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ์„ค์ • ๊ฐ์ฒด๋Š” ๋‹ค์–‘ํ•œ ์„ค์ • ๊ฐ’์„ ํฌํ•จํ•˜๋ฉฐ, ๋ณต์‚ฌ๋œ ์„ค์ • ๊ฐ์ฒด๋Š” ์›๋ณธ๊ณผ ๊ฐ™์€ ์ฐธ์กฐ๋ฅผ ๊ฐ–๋Š” ์†์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ์„ค์ • ๊ฐ’์„ ๊ณต์œ ํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์— ์–•์€ ๋ณต์‚ฌ๊ฐ€ ์ ํ•ฉ๋‹ค.

์˜ˆ์‹œ์ฝ”๋“œ

class Configuration implements Cloneable {
    private String name;
    private Map<String, String> settings;

    public Configuration(String name, Map<String, String> settings) {
        this.name = name;
        this.settings = settings;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // ์–•์€ ๋ณต์‚ฌ
    }

    // Getters and Setters
}

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Map<String, String> settings = new HashMap<>();
        settings.put("theme", "dark");
        
        Configuration original = new Configuration("appConfig", settings);
        Configuration copy = (Configuration) original.clone();

        // Both original and copy share the same settings map
        copy.getSettings().put("language", "en");

        System.out.println(original.getSettings()); // Output: {theme=dark, language=en}
        System.out.println(copy.getSettings());    // Output: {theme=dark, language=en}
    }
}

 

์„ค๋ช…

  • Configuration ๊ฐ์ฒด๋ฅผ ์–•์€ ๋ณต์‚ฌํ•˜๋ฉด, settings ๋งต์€ ์›๋ณธ๊ณผ ๋ณต์‚ฌ๋ณธ์ด ๋™์ผํ•œ ์ฐธ์กฐ๋ฅผ ๊ณต์œ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ copy์—์„œ settings๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด original์—์„œ๋„ ๊ฐ™์€ ๋ณ€๊ฒฝ์ด ๋‚˜ํƒ€๋‚œ๋‹ค. ์ด ๊ฒฝ์šฐ, ์„ค์ • ๊ฐ’์„ ๊ณต์œ ํ•ด๋„ ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์–•์€ ๋ณต์‚ฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๊นŠ์€ ๋ณต์‚ฌ Deep Copy

์ •์˜

๊นŠ์€ ๋ณต์‚ฌ๋Š” ๊ฐ์ฒด์™€ ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ๋ณต์‚ฌํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์›๋ณธ ๊ฐ์ฒด์™€ ๋ณต์‚ฌ๋œ ๊ฐ์ฒด๋Š” ์™„์ „ํžˆ ๋…๋ฆฝ์ ์ธ ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๋ฉฐ, ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋“ค๋„ ๋ชจ๋‘ ์ƒˆ๋กœ ์ƒ์„ฑ๋œ๋‹ค.-> ๋ณต์‚ฌ๋ณธ์„ ์ˆ˜์ •ํ•ด๋„ ์›๋ณธ์€ ์˜ํ–ฅ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.

๋ฐฉ๋ฒ•

  • ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด clone() ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ์ฐธ์กฐ ํƒ€์ž…์˜ ํ•„๋“œ๊นŒ์ง€ ๋ณต์‚ฌํ•ด์•ผ ํ•œ๋‹ค. ๋˜๋Š” ๊ฐ์ฒด์˜ ๋ณต์‚ฌ ์ƒ์„ฑ์ž(constructor) ๋˜๋Š” ๋ณต์‚ฌ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ์ œ

class Address implements Cloneable {
    private String city;
    private String street;

    public Address(String city, String street) {
        this.city = city;
        this.street = street;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // Address ๊ฐ์ฒด์˜ ์–•์€ ๋ณต์‚ฌ
    }

    // Getters and Setters
}

class Person implements Cloneable {
    private String name;
    private int age;
    private Address address;

    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person cloned = (Person) super.clone();
        cloned.address = (Address) address.clone(); // Address ๊ฐ์ฒด์˜ ๊นŠ์€ ๋ณต์‚ฌ
        return cloned;
    }

    // Getters and Setters
}

 

์‚ฌ์šฉ ์˜ˆ

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

์ƒํ™ฉ

  • ๊ฒŒ์ž„ ์บ๋ฆญํ„ฐ ๋ณต์‚ฌ: ๊ฒŒ์ž„์—์„œ ์บ๋ฆญํ„ฐ๋ฅผ ๋ณต์‚ฌํ•  ๋•Œ, ๊ฐ ์บ๋ฆญํ„ฐ๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘ํ•˜๊ณ  ์ž์‹ ์˜ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค. ์บ๋ฆญํ„ฐ๊ฐ€ ์žฅ์ฐฉํ•œ ์•„์ดํ…œ์ด๋‚˜ ์ƒํƒœ ์ •๋ณด๊นŒ์ง€ ์™„์ „ํžˆ ๋…๋ฆฝ์ ์œผ๋กœ ๋ณต์‚ฌํ•ด์•ผ ํ•  ๊ฒฝ์šฐ ๊นŠ์€ ๋ณต์‚ฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ

class Item implements Cloneable {
    private String name;

    public Item(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // ์–•์€ ๋ณต์‚ฌ
    }

    // Getters and Setters
}

class Character implements Cloneable {
    private String name;
    private List<Item> items;

    public Character(String name, List<Item> items) {
        this.name = name;
        this.items = items;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Character cloned = (Character) super.clone();
        cloned.items = new ArrayList<>();
        for (Item item : this.items) {
            cloned.items.add((Item) item.clone()); // ๊นŠ์€ ๋ณต์‚ฌ
        }
        return cloned;
    }

    // Getters and Setters
}

public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        List<Item> items = new ArrayList<>();
        items.add(new Item("Sword"));
        
        Character original = new Character("Hero", items);
        Character copy = (Character) original.clone();

        // Modify the copied character's items
        copy.getItems().get(0).setName("Shield");

        System.out.println(original.getItems().get(0).getName()); // Output: Sword
        System.out.println(copy.getItems().get(0).getName());    // Output: Shield
    }
}

 

์„ค๋ช…

  • Character ๊ฐ์ฒด์˜ ๋ณต์‚ฌ๋ณธ์„ ๊นŠ์€ ๋ณต์‚ฌํ•˜๋ฉด, ๊ฐ ์บ๋ฆญํ„ฐ์˜ items ๋ฆฌ์ŠคํŠธ์™€ ๋ฆฌ์ŠคํŠธ์˜ ์•„์ดํ…œ๋“ค๋„ ๋…๋ฆฝ์ ์œผ๋กœ ๋ณต์‚ฌ๋œ๋‹ค. ๋”ฐ๋ผ์„œ copy์—์„œ ์•„์ดํ…œ์„ ์ˆ˜์ •ํ•ด๋„ original์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค. ์ด์ฒ˜๋Ÿผ ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ์œ ์ง€๋˜์–ด์•ผ ํ•  ๊ฒฝ์šฐ, ๊นŠ์€ ๋ณต์‚ฌ๊ฐ€ ์ ํ•ฉ๋‹ค.

 

์ฐจ์ด์ 

1. ๋ณต์‚ฌ ๋ฒ”์œ„

  • ์–•์€ ๋ณต์‚ฌ: ๊ฐ์ฒด ์ž์ฒด๋Š” ๋ณต์‚ฌ๋˜์ง€๋งŒ, ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋“ค์€ ๋ณต์‚ฌ๋˜์ง€ ์•Š๊ณ  ์ฐธ์กฐ๋งŒ ๋ณต์‚ฌ๋œ๋‹ค.
  • ๊นŠ์€ ๋ณต์‚ฌ: ๊ฐ์ฒด์™€ ๋ชจ๋“  ์ฐธ์กฐ ๊ฐ์ฒด๊ฐ€ ์žฌ๊ท€์ ์œผ๋กœ ๋ณต์‚ฌ๋œ๋‹ค.

2. ๋…๋ฆฝ์„ฑ

  • ์–•์€ ๋ณต์‚ฌ: ๋ณต์‚ฌ๋œ ๊ฐ์ฒด์™€ ์›๋ณธ ๊ฐ์ฒด๋Š” ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋“ค์„ ๊ณต์œ ํ•œ๋‹ค.
  • ๊นŠ์€ ๋ณต์‚ฌ: ๋ณต์‚ฌ๋œ ๊ฐ์ฒด์™€ ์›๋ณธ ๊ฐ์ฒด๋Š” ์™„์ „ํžˆ ๋…๋ฆฝ์ ์ด๋‹ค.

3. ์‚ฌ์šฉ ๋ชฉ์ 

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

ChatGPT์˜ ์ถœ์ฒ˜

์–•์€ ๋ณต์‚ฌ(Shallow Copy)์™€ ๊นŠ์€ ๋ณต์‚ฌ(Deep Copy)์— ๋Œ€ํ•œ ์„ค๋ช…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ถœ์ฒ˜์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  1. Oracle Java Documentation
    • Object.clone() Method
    • ์ด ๋ฌธ์„œ์—์„œ๋Š” clone() ๋ฉ”์†Œ๋“œ์™€ ์–•์€ ๋ณต์‚ฌ์— ๋Œ€ํ•œ ์„ค๋ช…์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  2. Java Programming Books
    • Effective Java by Joshua Bloch: ์ด ์ฑ…์—์„œ๋Š” Java์—์„œ์˜ ๊ฐ์ฒด ๋ณต์‚ฌ์™€ ๊ด€๋ จ๋œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ฃผ์ œ๋ฅผ ๋‹ค๋ฃจ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
    • Java: The Complete Reference by Herbert Schildt: ์ด ์ฑ…์—์„œ ๊ฐ์ฒด ๋ณต์‚ฌ์™€ ๊ด€๋ จ๋œ ๊ธฐ์ดˆ ๊ฐœ๋…์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
  3. Tutorials and Articles

์ด ์ถœ์ฒ˜๋“ค์—์„œ๋Š” ์–•์€ ๋ณต์‚ฌ์™€ ๊นŠ์€ ๋ณต์‚ฌ์˜ ๊ฐœ๋…๊ณผ ์ฐจ์ด์ , ๊ทธ๋ฆฌ๊ณ  ์ž๋ฐ”์—์„œ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์„ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.