adsense


Java: Identical test prog..........

ref: http://aeternum.egloos.com/1105776

동일함(identical)의 의미

모든 객체 지향 시스템은 생성된 객체에게 고유한 식별자(identity)를 부여한다대부분의 객체 지향 언어는 객체가 위치하고 있는 메모리 상의 주소를 객체의 식별자로 할당하고 이 주소 값을 사용하여 객체를 구별한다각 언어는 객체의 식별자를 비교할 수 있는 연산자를 제공하는데 Java의 경우 “==”와 “!=” 연산자를 사용한다두 참조가 가리키는 객체가 동일한 식별자를 가지는 경우즉 동일한 주소에 위치하는 경우 “==” 연산자는 true를 반환한다.

 

다음은 실세계의 고객을 표현하는 Customer 클래스를 나타낸 것이다. 고객이 상품을 구매할 때마다 구매액의1%가 마일리지로 적립된다적립된 마일리지는 다음 상품 구매 시 현금과 동일하게 사용할 수 있다.



Customer.java

package org.eternity.customer;

 

public class Customer {

private String customerNumber;

private String name;

private String address;

private long mileage;

 

public Customer(String customerNumber, String name, String address) {

this.customerNumber = customerNumber;

this.name = name;

this.address = address;

}

 

public void purchase(long price) {

mileage += price * 0.01;

}

 

public boolean isPossibleToPayWithMileage(long price) {

return mileage > price;

}

 

public boolean payWithMileage(long price) {

if (!isPossibleToPayWithMileage(price)) {

      return false;

}

      

mileage -= price;

return true;

}

 

public long getMileage() {

return mileage;

}

}


 

고객 개개인은 시스템 내에서 유일해야 하며 시스템은 고객의 구매 기록이나 마일리지 적립 상태를 지속적으로 추적할 수 있어야 한다각 고객이 유일하기 때문에 고객이 동일한 지를 판단하기 위해 메모리 주소를 비교하는“==” 연산자를 사용한다.

 

반면 10,000원이라는 금액은 시스템 내에 유일하게 존재할 필요가 없다내 계좌의 입금 내역에 찍힌 10,000원이라는 금액과카드 영수증에 출력된 10,000원은 동등한 금액이지만 이들이 반드시 동일한 객체일 필요는 없다금액의 경우 객체의 동일성(identity) 보다는 속성 값의 동등성(equality)을 더 중요하게 생각한다.

 

따라서 “==” 연산자를 사용하여 동일성을 판단하기 보다는 equals() 메소드를 오버라이딩하여 금액의 동등성을 테스트해야 한다. equals() 메소드를 오버라이딩 할 경우에는 hashCode() 메소드도 함께 오버라이딩해주는 것이 좋다다음은 금액을 클래스로 작성한 것이다.



Money.java

package org.eternity.customer;

 

import java.math.BigDecimal;

 

public class Money {

  private BigDecimal amount;


  public Money(BigDecimal amount) {

    this.amount = amount;

  }

 

  public Money(long amount) {

    this(new BigDecimal(amount));

  }


  public boolean equals(Object object) {

    if (this == object) {

      return true;

    }

            

    if (!(object instanceof Money)) {

      return false;

    }           

            

    return amount.equals(((Money)object).amount);

  }


  public int hashCode() {

    return amount.hashCode();

  }


  public Money add(Money added) {

    this.amount = this.amount.add(added.amount);

    return this;

  }


  public String toString() {

    return amount.toString();

  }

}



고객은 REFERENCE OBJECT의 일반적인 예이며금액은 VALUE OBJECT의 일반적인 예이다REFERENCE OBJECT는 유일하기 때문에 동일성 확인 시에 식별자를 사용하는 “==” 연산자를 사용할 수 있다. VALUE OBJECT의 경우 equals() 메소드를 사용하여 속성 값의 동등성을 비교해야 한다.


아마 이 시점에 이르면 자연스럽게 다음과 같은 질문이 떠오를 것이다금액과 같은 VALUE OBJECTREFERENCE OBJECT처럼 하나의 인스턴스만 유지하고 “==” 연산자를 사용하여 동일성을 비교할 수 없을까?왜 객체를 비교할 때 “==” 연산자와 equals() 메소드를 구별하여 적용해야 하는가근본적으로 REFERENCE OBJECT와 VALUE OBJECT를 구별하는 이유가 무엇인가  이에 대한 해답은 REFERENCE OBJECT 대신VALUE OBJECT를 사용함으로써 악명 높은 별칭(aliasing) 문제를 피할 수 있기 때문이다.


덧글

댓글 입력 영역


통계 위젯 (화이트)

2965
398
291184

통계 위젯 (블랙)

2965
398
291184

이 이글루를 링크한 사람 (블랙)

2