본문 바로가기
Java의 정석/java.lang 패키지 & 유용한 클래스

Object 클래스, equals() 메서드

by Hwanii_ 2023. 8. 30.
728x90
Object 클래스, equals()

ch9-1 Object 클래스

- 모든 클래스의 최고 조상. 오직 11개의 메서드만 가지고 있다.
(인스턴스 변수, 클래스 변수가 존재 하지 않는다)

- notify(), wait() 등은 스레드와 관련된 메서드 이다.

Object 클래스의 메서드는 다음과 같다.

protected Object clone() :
객체 자신의 복사본을 반환.
(오버라이딩 해서 사용 할 때, 접근제어자는 public으로 변경해줘야 한다)

public boolean equals(Object obj) :
객체 자신과 객체 obj가 같은 객체인지 알려 준다. (같으면 true를 반환)

protected void finalize() :
객체가 소멸될 때 가비지 컬렉터에 의해 자동 호출 된다.
이때 수행되어야 하는 코드가 있을 때 오버라이딩 한다.
(오버라이딩 해서 사용 할 때, 접근제어자는 public으로 변경해줘야 한다)

생성자와 반대되는 개념 이다. (생성자 : 객체 초기화 할 때 사용)

객체를 제거 할 때, 마무리 작업을 수행 할 수 있도록 하는 메서드 이다.

사실상 거의 사용 하지 않는 메서드 이다

public Class getClass() :
객체 자신의 클래스 정보를 담고 있는 Class 인스턴스를 반환.
(클래스 정보 == 설계도 정보)

public int hashCode() :
객체 자신의 해시코드를 반환.

public String toString() :
객체 자신의 정보를 문자열로 반환.

public void notify() :
객체 자신을 사용하려고 기다리는 스레드를 하나만 깨운다.

public void notifyAll() :
객체 자신을 사용하려고 기다리는 모든 스레드를 깨운다.

public void wait() :
public void wait(long timeout) :
public void wait(long timeout, int nanos) :

다른 스레드가 notify() 나 notifyAll() 을 호출할 때 까지,
현재 스레드를 무한히,
또는,
지정된 시간 (timeout, nanos) 동안 기다리게 한다.

(timeout은 천 분의 1초, nanos는 10에 9승 분의 1초 이다)

 

ch9-2 equals(Object obj)

- 객체 자신과 (this) 주어진 객체 (obj) 를 비교 한다.
같으면 true, 다르면 false.

- Object 클래스의 equals()는 객체의 주소를 비교 (참조변수 값 비교)

public boolean equals(Object obj) {
    return (this == obj);
}

예시 )
public boolean equals(Object obj) { //  equals() 메서드 오버라이딩 하기 (== 재정의)

    ProductVO pVO = (ProductVO) obj //  다운캐스팅

    if(this.pNum() == pVO.pNum()) {
    return true;
    }
    return false;
}

 

ch9-3 equals(Object obj) 의 오버라이딩

- 인스턴스 변수 (instance variable == iv) 의 값을 비교하도록 equals() 를 오버라이딩.

cv : 객체마다 공통 (공유)
iv : 객체마다 다름 (개별)

 

예제 01 )

 

class Value {
    int value;

    Value(int value) {

        this.value = value;
    }

 

class Ex9_1 {

    public static void main(String[] args) {

        Value v1 = new Value(10);
        Value v2 = new Value(10);

        System.out.println(v1.getClass());
        System.out.println(v2.getClass());

        if (v1.equals(v2))
            System.out.println("v1과 v2는 같습니다.");
        else
            System.out.println("v1과 v2는 다릅니다.");

    }   //  main()

}   //  main class

 

equals() 메서드의 기본 형태는 아래와 같다.

 

public boolean equals(Object obj) {

    return this == obj;
}

 

따라서,

equals() 메서드는 객체를 비교 하기 때문에,

new가 되어 메모리에 올라간 객체는 당연히 다른 주소값을 가지게 된다.

 

그래서,

두 객체가 같은 클래스 출신의 인스턴스 이더라도,

주소값이 다르기 때문에,

무조건 결과값은 false가 되게 된다.

 

 

참조변수 v1과 참조변수 v2의 객체들의 인스턴스 변수 중에,

int value가 존재 하며,

생성자로 인해서, this.value의 값이 10으로 초기화 되는 것을 볼 수 있다.

 

그래서,

주소값은 서로 다른 두 객체지만,

value의 값이 같기 때문에,

이 둘의 값을 equals() 메서드로 비교하여,

true를 반환 하고 싶으면 아래와 같이 재정의 하면 된다.

 

 

최고조상 자료형인 Object 자료형의 매개변수 obj에

어떤 객체가 인자로 들어왔을 때,

이 객체가 실제로 Value 라는 자료형이 맞아야만,

객체의 특정한 값을 비교 할 수 있기 때문에,

instanceof 연산자를 사용 했다.

 

[ Console ]

 

 

equals() 메서드를 재정의 했기 때문에, v1과 v2는 같다고 나오는 것을 확인.

 

추가로, getClass() 메서드를 사용 하면 아래와 같은 결과를 볼 수 있다.

 

 

예제 02 )

 

class Person {
    long id;    //  주민등록번호

    public boolean equals(Object obj) {
        if (obj instanceof Person)
            return id == ((Person) obj).id;
        else
            return false;
    }

    Person(long id) {
        this.id = id;
    }
}

 

class Ex9_2 {
    public static void main(String[] args) {
        Person p1 = new Person(8011081111222L);
        Person p2 = new Person(8011081111222L);

        if (p1.equals(p2))
            System.out.println("p1과 p2는 같은 사람입니다.");
        else
            System.out.println("p1과 p2는 다른 사람입니다.");
    }
}

 

원래는 서로 다른 객체기 때문에 둘을 비교하면 false를 반환 해야 하지만,

 

equals() 메서드를 재정의 해서, 두 객체의 id 라는 변수를 비교하기로 되어 있다.

 

각 객체의 id 라는 인스턴스 변수의 값은 동일 하기 때문에, true를 반환 하게 된다.

 

[ console ]

 

 

반응형