logo

Java의 Clone() 메소드

객체 복제는 객체의 정확한 복사본을 생성하는 것을 의미합니다. 현재 개체 클래스의 새 인스턴스를 만들고 이 개체의 해당 필드 내용과 정확히 일치하는 모든 필드를 초기화합니다.

Java에서 객체 복제를 수행하는 방법

Java에서 객체 복제를 생성하는 방법에는 아래에 언급된 세 가지 방법이 있습니다.



  1. 할당 연산자를 사용하여 참조 변수의 복사본 만들기
  2. clone() 메서드를 사용하여 복사본 만들기
  3. clone() 메소드 사용 – Deep Copy

1. 할당 연산자를 사용하여 생성 사본 참조 변수

Java에는 객체의 복사본을 생성하는 연산자가 없습니다. C++와 달리 Java에서는 할당 연산자를 사용하면 객체가 아닌 참조 변수의 복사본이 생성됩니다. 이는 예를 들어 설명할 수 있다. 다음 프로그램은 동일한 내용을 보여줍니다.

다음은 위 주제의 구현입니다.

자바








// Java program to demonstrate that assignment operator> // only creates a new reference to same object> import> java.io.*;> > // A test class whose objects are cloned> class> Test {> >int> x, y;> >Test()> >{> >x =>10>;> >y =>20>;> >}> }> > // Driver Class> class> Main {> >public> static> void> main(String[] args)> >{> >Test ob1 =>new> Test();> > >System.out.println(ob1.x +>' '> + ob1.y);> > >// Creating a new reference variable ob2> >// pointing to same address as ob1> >Test ob2 = ob1;> > >// Any change made in ob2 will> >// be reflected in ob1> >ob2.x =>100>;> > >System.out.println(ob1.x +>' '> + ob1.y);> >System.out.println(ob2.x +>' '> + ob2.y);> >}> }>

>

>

스위치 자바 프로그래밍
산출

10 20 100 20 100 20>

2. clone() 메서드를 사용하여 복사본 만들기

객체의 복사본이 만들어질 클래스에는 해당 클래스나 상위 클래스 중 하나에 공개 복제 메서드가 있어야 합니다.

f영화
  • clone()을 구현하는 모든 클래스는 복제된 객체 참조를 얻기 위해 super.clone()을 호출해야 합니다.
  • 클래스는 또한 생성하려는 객체 복제가 있는 java.lang.Cloneable 인터페이스를 구현해야 합니다. 그렇지 않으면 해당 클래스의 객체에서 복제 메소드가 호출될 때 CloneNotSupportedException이 발생합니다.

통사론:

protected Object clone() throws CloneNotSupportedException>

i) clone() 메소드 사용 - 얕은 복사

메모 – 아래 코드 예제에서 clone() 메서드는 다른 hashCode 값을 사용하여 완전히 새로운 객체를 생성합니다. 이는 해당 객체가 별도의 메모리 위치에 있음을 의미합니다. 그러나 테스트 개체 c가 Test2 내에 있기 때문에 기본 유형은 전체 복사를 달성했지만 이 테스트 개체 c는 여전히 t1과 t2 간에 공유됩니다. 이를 극복하기 위해 우리는 나중에 논의할 객체 변수 c에 대해 명시적으로 깊은 복사를 수행합니다.

자바




// A Java program to demonstrate> // shallow copy using clone()> import> java.util.ArrayList;> > // An object reference of this class is> // contained by Test2> class> Test {> >int> x, y;> }> > // Contains a reference of Test and> // implements clone with shallow copy.> class> Test2>implements> Cloneable {> >int> a;> >int> b;> >Test c =>new> Test();> >public> Object clone()>throws> CloneNotSupportedException> >{> >return> super>.clone();> >}> }> > // Driver class> public> class> Main {> >public> static> void> main(String args[])> >throws> CloneNotSupportedException> >{> >Test2 t1 =>new> Test2();> >t1.a =>10>;> >t1.b =>20>;> >t1.c.x =>30>;> >t1.c.y =>40>;> > >Test2 t2 = (Test2)t1.clone();> > >// Creating a copy of object t1> >// and passing it to t2> >t2.a =>100>;> > >// Change in primitive type of t2 will> >// not be reflected in t1 field> >t2.c.x =>300>;> > >// Change in object type field will be> >// reflected in both t2 and t1(shallow copy)> >System.out.println(t1.a +>' '> + t1.b +>' '> + t1.c.x> >+>' '> + t1.c.y);> >System.out.println(t2.a +>' '> + t2.b +>' '> + t2.c.x> >+>' '> + t2.c.y);> >}> }>

>

>

산출

10 20 300 40 100 20 300 40>

위의 예에서 t1.clone은 객체 t1의 얕은 복사본을 반환합니다. 개체의 전체 복사본을 얻으려면 복사본을 얻은 후 복제 방법에서 특정 수정을 수행해야 합니다.

ii) clone() 메소드 사용 – Deep Copy

  • 객체 X의 전체 복사본을 생성하여 새 객체 Y에 배치하려는 경우 참조된 객체 필드의 새 복사본이 생성되고 이러한 참조는 객체 Y에 배치됩니다. 이는 객체의 참조 객체 필드에 적용된 모든 변경 사항을 의미합니다. X 또는 Y는 해당 개체에만 반영되고 다른 개체에는 반영되지 않습니다. 아래 예에서는 객체의 전체 복사본을 생성합니다.
  • 전체 복사는 모든 필드를 복사하고 해당 필드가 가리키는 동적으로 할당된 메모리의 복사본을 만듭니다. 깊은 복사는 객체가 참조하는 객체와 함께 복사될 때 발생합니다.

자바




// A Java program to demonstrate> // deep copy using clone()> > // An object reference of this> // class is contained by Test2> class> Test {> >int> x, y;> }> > // Contains a reference of Test and> // implements clone with deep copy.> class> Test2>implements> Cloneable {> >int> a, b;> > >Test c =>new> Test();> > >public> Object clone()>throws> CloneNotSupportedException> >{> >// Assign the shallow copy to> >// new reference variable t> >Test2 t = (Test2)>super>.clone();> > >// Creating a deep copy for c> >t.c =>new> Test();> >t.c.x = c.x;> >t.c.y = c.y;> > >// Create a new object for the field c> >// and assign it to shallow copy obtained,> >// to make it a deep copy> >return> t;> >}> }> > public> class> Main {> >public> static> void> main(String args[])> >throws> CloneNotSupportedException> >{> >Test2 t1 =>new> Test2();> >t1.a =>10>;> >t1.b =>20>;> >t1.c.x =>30>;> >t1.c.y =>40>;> > >Test2 t3 = (Test2)t1.clone();> >t3.a =>100>;> > >// Change in primitive type of t2 will> >// not be reflected in t1 field> >t3.c.x =>300>;> > >// Change in object type field of t2 will> >// not be reflected in t1(deep copy)> >System.out.println(t1.a +>' '> + t1.b +>' '> + t1.c.x> >+>' '> + t1.c.y);> >System.out.println(t3.a +>' '> + t3.b +>' '> + t3.c.x> >+>' '> + t3.c.y);> >}> }>

안드로이드에서 유튜브 광고 차단하기

>

>

산출

10 20 30 40 100 20 300 40>

위의 예에서는 Test 클래스의 새 객체가 clone 메소드에 반환될 객체를 복사하기 위해 할당되었음을 알 수 있습니다. 이로 인해 t3은 객체 t1의 깊은 복사본을 얻습니다. 따라서 t3에 의해 'c' 개체 필드에 적용된 모든 변경 사항은 t1에 반영되지 않습니다.

깊은 복사와 얕은 복사

아래에 언급된 것처럼 clone()을 전체 복사본으로 사용하는 것과 얕은 복사본으로 사용하는 것에는 특정 차이점이 있습니다.

  • 얕은 사본 객체를 복사하는 방법으로 복제 시 기본적으로 따릅니다. 이 방법에서는 이전 객체 X의 필드가 새 객체 Y에 복사됩니다. 객체 유형 필드를 복사하는 동안 참조는 Y에 복사됩니다. 즉, 객체 Y는 X가 가리키는 것과 동일한 위치를 가리킵니다. 필드 값이 기본 유형은 기본 유형의 값을 복사합니다.
  • 따라서 객체 X 또는 Y의 참조 객체에 대한 모든 변경 사항은 다른 객체에 반영됩니다.

얕은 복사본은 저렴하고 만들기 쉽습니다. 위의 예에서는 다음의 얕은 복사본을 만들었습니다. 그만큼 물체.

clone 메소드()를 사용하는 이유 또는 복제 방법의 장점

  • 할당 연산자를 사용하여 개체 참조를 다른 참조 변수에 할당하면 이전 개체의 동일한 주소 위치를 가리키며 개체의 새 복사본이 생성되지 않습니다. 이로 인해 참조 변수의 모든 변경 사항이 원본 개체에 반영됩니다.
  • 복사 생성자를 사용하는 경우 모든 데이터를 명시적으로 복사해야 합니다. 즉 생성자에 있는 클래스의 모든 필드를 명시적으로 다시 할당해야 합니다. 그러나 clone 메소드에서는 새로운 복사본을 생성하는 작업이 메소드 자체에 의해 수행됩니다. 따라서 추가 처리를 피하기 위해 객체 복제를 사용합니다.