equals는 객체와 객체가 같은 것인지를 비교하는 API이다. 객체 간에 같고 다름은 필요에 따라서 달라질 수 있기 때문이다.
package org.opentutorials.javatutorials.progenitor; class Student{ String name; Student(String name){ this.name = name; } public boolean equals(Object obj) { Student _obj = (Student)obj; return name == _obj.name; } } class ObjectDemo { public static void main(String[] args) { Student s1 = new Student("egoing"); Student s2 = new Student("egoing"); System.out.println(s1 == s2); System.out.println(s1.equals(s2)); } }
결과는 아래와 같다.
false true
아래 코드를 보자.
System.out.println(s1 == s2);
결과는 false다.
그 이유는 s1과 s2가 서로 다른 객체이기 때문이다. 어찌 보면 당연한 결과다. 하지만 두 개의 객체가 논리적으로는 egoing이라는 값을 가지고 있기 때문에 객체를 만든 필자는 저 두 개의 객체가 같은 객체로 간주 되었으면 좋겠다. 이럴 때 클래스 Object의 메소드 equals를 overiding하면 된다.
public boolean equals(Object obj) { Student _obj = (Student)obj; return name == _obj.name; }
위의 코드 (Student)obj 는 메소드 equals로 전달된 obj의 데이터 타입이 Object이기 때문에 이를 Student 타입으로 형 변환하는 코드다. 아래 코드를 통해서 현재 객체의 변수 name과 equals의 인자로 전달된 객체의 변수 name을 비교한 결과를 Boolean 값으로 리턴하고 있다. 이 값에 따라서 두 개의 객체는 같거나 다른 것이 된다.
return name == _obj.name;
그런데 eqauls를 제대로 사용하기 위해서는 hashCode라는 클래스도 함께 구현해야 한다. 하지만 이에 대한 이야기는 우리 수업의 범위를 넘어서고 그 효용(사용 빈도)도 높지 않기 때문에 더 이상 설명을 하지 않겠다. 하지만 이 메소드의 취지를 이해하는 것은 또한 중요하기 때문에 언급을 하지 않을 수는 없었다. 메소드 equals에 대해서 필자가 권고하는 입장은 아래와 같다.
1. 객체 간에 동일성을 비교하고 싶을 때는 ==를 사용하지 말고 equals를 이용하자.
2. equals를 직접 구현해야 한다면 hashCode도 함께 구현해야 함을 알고 이에 대한 분명한 학습을 한 후에 구현하자.
3. equals를 직접 구현해야 한다면 eclipse와 같은 개발도구들은 equals와 hashCode를 자동으로 생성해주는 기능을 가지고 있다. 이 기능을 이용하는 것을 고려해보자. 아래 그림을 참고하자.
4. 그 이유가 분명하지 않다면 비교 연산자 == 은 원시 데이터형을 비교할 때만 사용하자.