[자바/JAVA] 많이 활용되는 equals(Object obj) 메서드, 구현부 의미는

자바 개발 툴인 JDK에는 기본적으로 제공되는 모듈(Module)들이 있다. 프로그래밍에서 모듈이란 프로그램을 구성하는 단위 구성요소다. 일종의 부품이랄까. 보통 클래스와 라이브러리로 구성된다.

 

기본으로 제공하는 기능이 있으면 감사히 쓰면 된다. 그중 활용도가 높은 메서드인 equals(Object obj)를 정리한다.

Class Object의 존재

자바에는 상속이라는 개념이 있다. 클래스 간 상속을 통해 구성 요소나 기능을 받아오는 개념이다. B라는 이름의 클래스가 A 클래스를 상속받는 걸

class B extends A {} // B 클래스가 A 클래스를 상속받음

이렇게 표현한다.

 

그런데 프로젝트 내에 존재하는 모든 클래스의 조상이 되는 클래스가 있다. Object 클래스다. Object 클래스는 따로 만들지 않아도 JDK에 기본적으로 존재한다. 즉

class A {}

class A extends Object {}

와 같은 의미다. 이는 모든 클래스는 Object 클래스에 있는 메서드를 마음껏 오버라이딩해서 사용할 수 있다는 의미로 이어진다.

 

Java Development Kit (JDK) APIs 문서에서 JDK에 포함된 모듈을 모두 확인할 수 있다. Object 클래스의 경우

java.base >> java.lang >> Object

경로에서 확인할 수 있다. equals(Object obj)는 Object 클래스의 메서드 중 하나다.

class Object에 있는 메서드들

equals(Object obj)

프로그래밍에서 하나의 값과 다른 값을 비교하다보면 가끔 문제에 마주치곤 하는데 예를 들면 이런 상황이다. a와 b 두 변수에는 결론적으로 같은 값이 들어 있다. 사람이 보기엔 딱 봐도 둘은 같다. 그러나 컴퓨터는 가리키는 주소 값이 다르면 둘을 다르다고 결론짓는다. 난감한 상황이지만 equals(Object obj)를 사용하면 문제를 해결할 수 있다.

 

예시를 통해 알아보자.

class Value {
    int value;

Value(int value) {
        this.value = value;
    }
}

Value라는 클래스에 int형 변수 value를 선언하고 int형 매개변수를 받고 초기화하는 생성자를 구현했다.

class EqualsEx1 {
    public static void main(String[] args) {
        Value v1 = new Value(10);
        Value v2 = new Value(10);
    }
}

EqualsEx1 클래스에 메인메서드를 통해 객체를 생성하고 각각 참조변수 v1과 v2에 10을 넣었다. 두 값을 출력하면 모두 10으로 같다.

if (v1.equals(v2)) {// 주소값을 비교
            System.out.println("v1과 v2는 같습니다.");
        } else {
            System.out.println("v1과 v2는 다릅니다.");
        }

equals() 메서드를 통해 v1과 v2를 비교하면 결과는

v1과 v2는 다릅니다.

가 출력된다. 두 참조변수의 주소 값이 다르기 때문이다.

 

어? equals()==와 달리 실제 값을 비교하는 연산자 아닌가? 라고 생각할 수도 있는데, 그건 데이터 타입이 String일 경우다.

v2 = v1; // v2에 v1의 주소값을 대입

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

실제로 v2에 v1의 주소를 대입하면 출력 값은

v1과 v2는 같습니다.

가 나오는 걸 알 수 있다.

 

값이 같으면 같다고 인식하게 만드는 작업을 진행해야 한다.

class Value extends Object{ // extedns Object는 생략 가능
    int value;

    //equals() 오버라이딩
    @Override
    public boolean equals(Object obj) { 
        if(obj != null && obj instanceof Value) {
            return value == ((Value)obj).value; 
        } else {
            return false;
        }
    }

    Value(int value) {
        this.value = value;
    }
}

Value 클래스에 오버라이딩을 진행했다. 생각보다 복잡해 보이긴 하지만 잘 뜯어보면 이해 못할 내용도 아니다.

우선 public boolean equals(Object obj)에서 boolean은 참거짓(true, false)을 반환하는 데이터 타입이다. equals(Object obj)는 데이터 타입이 Object인 obj 값을 받는 equals 메서드라는 의미다.

 

구현부{}에서는 조건문 if를 통해 주소 값과 실제 저장된 값을 동일하게 인식하게 해주는 작업을 진행한다. obj != null 은 obj가 null이 아니라는 뜻이니 비교할 값이 있다는 의미다. &&(AND) obj instanceof Value 는 Object 타입의 obj를 Value 타입으로 형변환할 수 있는지 여부를 확인하는 연산이다.

 

즉 비교할 값이 있고 obj를 Value 타입으로 형변환할 수 있으면 return value == ((Value)obj).value; 변수에 저장된 값과 참조변수를 통해 접근한 주소 값을 같게 한다는 의미다.

 

그렇지 않을 경우엔 return false;를 반환하도록 코딩한다.

 

이런 작업을 거치고 나서

if (v1.equals(v2)) {// 주소 값을 비교
            System.out.println("v1과 v2는 같습니다.");
        } else {
            System.out.println("v1과 v2는 다릅니다.");
        }

를 실행하면

v1과 v2는 같습니다.

를 출력한다.

반응형

댓글

Designed by JB FACTORY