⚙️ Backend/JAVA

JAVA - Clone에 관하여..

코너(Corner) 2020. 11. 30.
반응형

  Object 클래스의 클론을 쓰면 얕은 복제 기본형복사 객체형 주소 복사 

  Car c = new Car(); // c라는 주소의 카피는 오리지날의 주소와 같은 값 원본을 바꾸면 카피본이 바뀐다. 

  == 같은 주소를 가리키니까. - 객체 참조 변수의 가르키는 주소가 동일하므로 참조변수 값을 바꾸면 같이 바뀐다.

 

  -깊은 복제 : 자손 클래스가 부모 클래스 (Object클래스 clone();) - 자손 클래스가 재정의해서 clone() 한번 수행

  - 참조변수의 가르키는 주소를 다른 것으로 복사 - 원본의 참조변수의 값을 바꾸면 바뀌지 않는다.

 

c1= original

c2 = shalldow Copy

c3 = deep Copy 

c3는 깊은 복제 이므로 c1.p.x , c1.p.y 의 값을 바꾸어도 변하지 않는다. 왜냐하면 c3는 새로운 참조변수를 가지고 있으니까.

c2는 오리지날의 참조변수 즉, c1을 그대로 가리키므로 변하지 않는다.

 


package Clone에관하여;

class Point {
	int x, y;

	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}

	@Override
	public String toString() {
		return "(" + x + ", " + y + ")";
	}
}

class Circle implements Cloneable {
	Point p;
	double r;

	public Circle(Point p, double r) {
		this.p = p;
		this.r = r;
	}

	// 클론 오버라이드
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Object obj = null;
		obj = super.clone(); // 부모 클래스의 클론을 돌린것
		return super.clone();
	}

	// 얕은 복사
	public Circle shallowCopy() {
		Object obj = null;
		try {
			obj = super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return (Circle) obj; // Object 형이였던 객체를 Circle 타입으로 변환해서 리턴
	}

	// 깊은 복사
	public Circle deepCopy() {
		Object obj = null;
		try {
			obj = super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Circle c = (Circle) obj; // 다운 캐스팅
		c.p = new Point(this.p.x, this.p.y); // 안에 실제 내용을 넣기
		return c;
	}

	@Override
	public String toString() {
		return "[p = " + p + ", r = " + r + "]";
	}
}
/*
 Object 클래스의 클론을 쓰면 얕은 복제 . 기본형 값 복사하고(스택메모리니깐) 객체형은 주소를 복사
 
 Car c = new Car(); // c라는 주소의 카피는 오리지날의 주소와 같은 값 원본을 바꾸면 카피본이 바뀐다. 
 == 같은 주소를 가리키니까. - 객체 참조 변수의 가르키는 주소가 동일하므로 참조변수 값을 바꾸면 같이 바뀐다.
  
  -깊은 복제 : 자손 클래스가 부모 클래스 (Object클래스 clone();) - 자손 클래스가 재정의해서 clone() 한번 더 수행
  - 참조변수의 가르키는 주소를 다른 것으로 복사 - 원본의 참조변수의 값을 바꾸면 바뀌지 않는다.
 */  
	 
	public class ShallDeepCopyEx {
		public static void main(String[] args) {
			Circle c1 = new Circle(new Point(1, 1), 2.0);
			Circle c2 = c1.shallowCopy(); //얕은복제
			Circle c3 = c2.deepCopy(); // 깊은 복제
			System.out.println("==========C1의 변경전===========");
			System.out.println("c1 = "+c1);
			System.out.println("c2 = "+c2);
			System.out.println("c3 = "+c3); // 깊은복제
			
			c1.p.x=9;
			c1.p.y=9;
			System.out.println("");
			System.out.println("==========c1의 변경후 ===========");
			System.out.println("c1="+c1);
			System.out.println("c2="+c2);
			System.out.println("c3="+c3); // 원본의 값을 변경해도 깊은 복제  값이 바뀌지 않는다.
			/* 
			 * - Circle c = (Circle) obj;
			 * c.p = new Point(this.p.x, this.p.y);
			 * 이 두줄로 인해 복제된 객체가 새로운 Point 인스턴스를 참조하도록 했다.
			 * 원본이  참조하고 있는 객체까지 복사한 것이다.
			 */
			
			
	}

}

 

 

 

반응형

댓글