본문 바로가기

Java

Java 문법 - hashCode(), 객체 복제

@markdown


## hashCode() 함수 재정의 활용

____

<pre><code class="java" style="font-size:14px">@Override

public int hashCode(){

    return name.hashCode; //같은 name으로 생성되는 hashCode가 같도록 하게끔 재정의

}

</code></pre>


## 객체 복제 - clone()

____

- 원본 객체의 필드 값과 동일한 값을 가지는 새로운 객체 생성하는 것

- 복제 종류


  1. 얕은 복제(thin clone): 필드 값만 복제 (참조 타입 필드는 번지 공유)

  2. 깊은 복제(deep clone): 참조하고 있는 객체도 복제


## Object의 clone() 메소드

____

  - 동일한 필드 값 을 가진 얕은 복제된 객체 리턴

  - java.lang.Cloneable 인터페이스 구현한 객체만 복제 가능

  - 깊은 복제 - clone() 메소드 재정의하고 참조 객체도 복제해야함


## 얕은 복제 코드

____

<pre><code class="java" style="font-size:14px">class Pen extends Object implements Cloneable{

String model;

int price;

int[]arr = { 10, 20, 30 };

public Pen(String model, int price) {

super();

this.model = model;

this.price = price;

}


@Override

protected Object clone() throws CloneNotSupportedException {

//깊은 복제를 하고 싶으면 이 부분에 코드 작성

return super.clone(); //기존의 기능을 사용하는 것은 얕은 복제

}


@Override

public String toString() {

return "Pen [model=" + model + ", price=" + price + ", arr="

+ Arrays.toString(arr) + "]";

}

}

</code></pre>

<pre><code class="java" style="font-size:14px">public class CloneTest {

  public static void main(String[] args) throws CloneNotSupportedException {

  Pen p1 = new Pen("모나미", 2000);

  Pen p2 = p1; //복제가 아니라 주소를 복사한 것\

  p2.price = 4000;

  System.out.println(p1 == p2); //같은 주소를 참조하고 있다.

  p2.arr[0] = 11;

  //같은 주소를 참조하고 있기 때문에 p2에서 바뀐 값이 같이 반영됨

  System.out.println(p1);

  System.out.println(p2);


  Pen p3 = (Pen)p1.clone(); //Cloneable 인터페이스를 구현해야지만 clone()을 할 수 있다.

  p3.price = 9999;

  p3.arr[0] = 99;

  System.out.println(p1 == p3); //복제가 됐기 때문에 다른 주소를 사용한다.

  System.out.println(p1);

  //복제됐기 때문에 p3 가격만 바뀜

  System.out.println(p3);

  }

  }

</code></pre>


<pre><code class="java" style="font-size:14px">실행결과

 true

 Pen [model=모나미, price=4000, arr=[11, 20, 30]]

 Pen [model=모나미, price=4000, arr=[11, 20, 30]]

 false

 Pen [model=모나미, price=4000, arr=[99, 20, 30]]

 Pen [model=모나미, price=9999, arr=[99, 20, 30]]

 //배열의 경우 복제가 이루어지지 않음

 </code></pre>


## 깊은 복제 코드

_____

- clone() 부분 깊은 복제 할 코드를 직접 넣어 배열 복사

<pre><code class="java" style="font-size:14px">@Override

protected Object clone() throws CloneNotSupportedException {

//깊은 복제를 하고 싶으면 이 부분에 코드 작성

Pen pen = (Pen)(super.clone());

pen.arr = Arrays.copyOf(arr, arr.length); //참조형은 별도코드 필요

//기존의 기능을 사용하는 것은 얕은 복제

return pen;

}

</code></pre>

<pre><code class="java" style="font-size:14px">실행결과

 true

 Pen [model=모나미, price=4000, arr=[11, 20, 30]]

 Pen [model=모나미, price=4000, arr=[11, 20, 30]]

 false

 Pen [model=모나미, price=4000, arr=[11, 20, 30]]

 Pen [model=모나미, price=9999, arr=[99, 20, 30]]

 //arr[0]의 값만 바뀜, 깊은 복제 이루어짐

</code></pre>


## Class 깊은 복제 코드

_____

<pre><code class="java" style="font-size:14px">class Bag{

String brand;

public Bag(String brand){

this.brand = brand;

}

}


Pen {

...

Bag bag = new Bag("ABCD");

    @Override

  protected Object clone() throws CloneNotSupportedException {

  //깊은 복제를 하고 싶으면 이 부분에 코드 작성

    Pen pen = (Pen)(super.clone());

    pen.arr = Arrays.copyOf(arr, arr.length); //참조형은 별도코드 필요

    pen.bag = new Bag(bag.brand);

  //기존의 기능을 사용하는 것은 얕은 복제

  return pen;

  }

}

</code></pre>


## 객체 소멸자 - finalize()

____

- GC는 객체를 소멸하기 직전 객체 소멸자(finalize()) 실행

- Object의 finalize() 는 기본적으로 실행 내용이 없음

- 객체가 소멸되기 전에 실행할 코드가 있다면? finalize() 재정의!

- 될 수 있으면 소멸자는 사용하지 말 것 -> GC 구동 시점이 일정하지 않음

<pre><code class="java" style="font-size:14px">@Override

protected void finalize() Throwable {

  System.out.println(no + "번 객체의 finalize()가 실행됨");

}

</code></pre>