equals 메서드는 두 개의 개체가 같은지 판별하는 것이 디폴트입니다. 대신 값 형식과 일부 클래스(대표적으로 String 클래스)에서는 내부의 값이 같은지 판별합니다.
다음의 예제 코드는 equals 메서드를 재정의할 때와 하지 않을 때를 비교하기 위한 예제입니다. MyData 클래스에서는 equals 메서드를 재정의하였고 MyInt 클래스에서는 재정의하지 않았습니다.
그리고 테스트 코드에서는 같은 값을 갖는 MyData 개체를 두 개 생성한 후에 equals 메서드로 비교하고 == 연산자로 비교합니다. 클래스 형식의 equals 메서드 디폴트 동작은 같은 개체를 참조하는지를 비교하는 것이기 때문에 결과는 false입니다. 물론 == 연산의 결과도 마찬가지입니다.
MyData md1 = new MyData(1); MyData md2 = new MyData(1); System.out.println(md1.equals(md2)); System.out.println(md1==md2);
하지만 같은 값을 갖는 MyInt 개체를 두 개 생성한 후에 equals 메서드 호출하면 개발자가 정한 코드가 동작하기 때문에 개발자 의도에 맞게 내부 값만 같아도 true값을 반환하게 정의할 수 있습니다.
public class MyInt { int value; public MyInt(int value){ this.value = value; } public boolean equals(Object obj){ if(obj instanceof MyInt){ MyInt mi = (MyInt)obj; return value == mi.value; } return false; } }
이처럼 정의하면 같은 값을 갖는 두 개의 MyInt 개체를 equals 메서드로 비교하면 true 값을 반환합니다. 물론 이 때도 == 연산의 결과는 false입니다.
MyInt mi1 = new MyInt(1); MyInt mi2 = new MyInt(1); System.out.println(mi1.equals(mi2)); System.out.println(mi1==mi2);
다음은 equals 메서드를 재정의하지 않은 MyData 클래스와 재정의한 MyInt 클래스를 상호 비교하는 예제입니다.
//equals 메서드를 재정의하지 않은 MyData 클래스 public class MyData { int num; public MyData(int num){ this.num = num; } }
//equals 메서드를 재정의한 MyInt 클래스 public class MyInt { int value; public MyInt(int value){ this.value = value; } public boolean equals(Object obj){ if(obj instanceof MyInt){ MyInt mi = (MyInt)obj; return value == mi.value; } return false; } }
//equals 메서드 재정의 예 public class Program { public static void main(String[] args){ MyData md1 = new MyData(1); MyData md2 = new MyData(1); System.out.println(md1.equals(md2)); System.out.println(md1==md2); MyInt mi1 = new MyInt(1); MyInt mi2 = new MyInt(1); System.out.println(mi1.equals(mi2)); System.out.println(mi1==mi2); } }
실행 결과
false false true false