[JAVA] clone() ๋ฉ”์„œ๋“œ ์ •๋ฆฌ

Object ํด๋ž˜์Šค์˜ clone ๋ฉ”์„œ๋“œ์— ๊ด€ํ•œ ๊ฐ„๋žตํ•œ ๊ธฐ๋ก์ด๋‹ค.

 

clone ๋ฉ”์„œ๋“œ๋Š” Cloneable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†ํ•˜์ง€ ์•Š์œผ๋ฉด ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ์‚ฌ์šฉ ์‹œ CloneNotSupportedException์„ ํ•ธ๋“ค๋งํ•ด์•ผ ํ•œ๋‹ค. (Checked Exception ์ด๋ฏ€๋กœ)

 

์ด๋ฆ„์—์„œ ๋Œ€๋žต์ ์œผ๋กœ ์œ ์ถ”๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ฃผ์†Œ๊ฐ’๋งŒ ๊ฐ€์ ธ์˜ค๋Š” ์–•์€ ๋ณต์‚ฌ๊ฐ€ ์•„๋‹Œ ๋‚ด์šฉ์ด ๊ฐ™๊ณ  ์ฃผ์†Œ๊ฐ€ ๋‹ค๋ฅธ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

 

๋‹ค์Œ๊ณผ ๊ฐ™์ด Cloneable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” CloneableObject ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•œ๋‹ค.

public class CloneableObject implements Cloneable {

        String msg;

        public CloneableObject(String msg) {
            this.msg = msg;
        }

        @Override
        public CloneableObject clone() {
            try {
                return (CloneableObject) super.clone();
            } catch (CloneNotSupportedException e) {
                throw new AssertionError();
            }
        }
    }

๊ทธ๋ฆฌ๊ณ  ์œ„์˜ ๊ฐ์ฒด๋ฅผ ์‹ค์ œ๋กœ ์ƒ์„ฑํ•˜๊ณ  clone ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋ณต์‚ฌ๋ฅผ ์‹คํ–‰ํ•œ ํ›„ ์ฃผ์†Œ๊ฐ’๊ณผ ๊ฐ์ฒด์˜ ๋‚ด์šฉ์„ ๋น„๊ตํ•ด๋ณด๋„๋ก ํ•˜์ž.

@Test
    public void cloneTest() {
        //given
        CloneableObject objectA = new CloneableObject("MSG");
        //when
        CloneableObject objectB = objectA.clone();
        //then
        System.out.println("objectA = " + objectA);
        System.out.println("objectB = " + objectB);
        System.out.println("objectA.hash = " + objectA.hashCode());
        System.out.println("objectB.hash = " + objectB.hashCode());
        System.out.println("objectA.msg = " + objectA.msg);
        System.out.println("objectB.msg = " + objectB.msg);

        Assertions.assertThat(objectA).isNotSameAs(objectB);
        Assertions.assertThat(objectA).isNotEqualTo(objectB);
        Assertions.assertThat(objectA.msg).isEqualTo(objectB.msg);
    }

๊ฐ์ฒด์˜ ์ฃผ์†Œ๊ฐ’, ํ•ด์‰ฌ์ฝ”๋“œ ๋ชจ๋‘ ๊ธฐ์กด ๊ฐ์ฒด์™€ ๋‹ค๋ฅธ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์ง€๋งŒ, ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๊ฐ€ ๊ฐ–๋Š” ๊ฐ’์€ ๋™์ผํ•œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํ˜น์‹œ CloneableObject ์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ ๊ฐ์ฒด์˜ ์ฐธ์กฐ๊ฐ’์„ ํฌํ•จํ•œ๋‹ค๋ฉด, clone ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ์‹œ์— ์–ด๋–ค ๋ณต์‚ฌ๋ฅผ ์‹ค์‹œํ• ๊นŒ?

๋‹ค์Œ๊ณผ ๊ฐ™์€ Member ํด๋ž˜์Šค๋ฅผ ์ •์˜ ํ›„ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋กœ ํฌํ•จ์‹œ์ผœ๋ณด๋„๋ก ํ•˜์ž.

public class Member {

    public String name;
    public int age;

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

}

CloneableObject๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•œ๋‹ค.

public class CloneableObject implements Cloneable {

    String msg;
    Member member;

    public CloneableObject(String msg, Member member) {
        this.msg = msg; this.member = member;
    }

    @Override
    public CloneableObject clone() {
        try {
            return (CloneableObject) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }

}

์ดํ›„ ์œ„์—์„œ ์‹คํ–‰ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ด Member ๊ฐ์ฒด๋งŒ ์ถ”๊ฐ€ํ•˜์—ฌ clone์„ ์‹คํ–‰ํ•˜๊ณ , Member ๊ฐ์ฒด์˜ ์ฃผ์†Œ๊ฐ’์„ ํ™•์ธํ•ด๋ณด์ž

@Test
    public void innerCloneTest() {
        //given
        Member member = new Member("MemberName", 20);
        CloneableObject objectA = new CloneableObject("MSG", member);
        //when
        CloneableObject objectB = objectA.clone();
        //then
        System.out.println("objectA = " + objectA.member);
        System.out.println("objectB = " + objectB.member);
        System.out.println("objectA.hash = " + objectA.member.hashCode());
        System.out.println("objectB.hash = " + objectB.member.hashCode());

        Assertions.assertThat(objectA.member).isEqualTo(objectB.member);
        Assertions.assertThat(objectA.member).isSameAs(objectB.member);
    }

์ฐธ์กฐ๋ณ€์ˆ˜ ๋˜ํ•œ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์ฃผ์†Œ๊ฐ’ ์ž์ฒด๋ฅผ ๋ณต์ œ ํ•ด์˜ค๊ธฐ ๋•Œ๋ฌธ์— ๋‹น์—ฐํ•œ ๊ฒฐ๊ณผ์ด๊ฒ ์ง€๋งŒ, Member ๊ฐ์ฒด๋Š” ์™„์ „ํžˆ ๋™์ผํ•œ ์ฃผ์†Œ์™€ ๊ฐ’์œผ๋กœ ๋ณต์‚ฌ ๋˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

์ด ๋˜ํ•œ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์œผ๋ฉด Member ํด๋ž˜์Šค๋„ Cloneable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ clone ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜๊ณ  clone ์‹คํ–‰ ์‹œ ๋‚ด๋ถ€์˜ ๋ฉค๋ฒ„ ๊ฐ์ฒด๋“ค๋„ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ๋ณ„๋„๋กœ ์‹คํ–‰ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.