Objects
클래스의 메서드 중 toString()
에 이어 이번에는 equals()
를 살펴보도록 하겠다.
equals()
는 두 인스턴스의 주소값을 비교하여 같은 인스턴스인지를 확인하고 같으면 true
, 다르면 false
의 boolean
값을 리턴하는 메서드이다.
여기서 주소 값을 비교했을 때 당연히 값이 같다면 같은 인스턴스이다. 예시로 Student
라는 클래스를 만들어 비교를 해보자.
public class equalTest {
public static class Student {
String name;
int studentNum;
public Student (String name, int studentNum) {
this.name=name;
this.studentNum=studentNum;
}
}
public static void main(String[] args) {
Student st1 = new Student("kim",111);
Student st2 = new Student("lee",222);
Student st3= st1;
System.out.println(st1.equals(st2));
System.out.println(st1.equals(st3));
}
}
/* 출력결과
false
true
*/
st1
과 st2
는 명확하게 다른 인스턴스임을 알 수 있다. st3
은 st1
을 복사해온 것이므로 st1
과 같은 주소값을 가리키고 있다. 따라서 같은 인스턴스를 공유하고 있다.
그런데 이렇게 주소가 같은 경우(물리적으로 동일) 뿐만 아니라 논리적으로 두 인스턴스가 동일하다고 판단될 때도 equals()를 재정의하여 사용한다.
논리적으로 동일한 두 인스턴스란?
방금 만든 Student객체에서 Student st4= new Student("kim",111);
로 새로운 객체를 생성 해보자. 그렇다면 st4
는 st1
과 이름과 학번이 모두 동일한 같은 학생이다. st1
과 st4
가 가리키는 인스턴스는 다르지만, 논리적으로 봤을 때 같은 학생이라는 것이다. 이런 경우는 st1과 st4를 같은 학생으로 처리해야 맞는 결과이다.
따라서 equals()
를 오버라이딩하여 이런 경우도 프로그램상 같다고 판단할 수 있도록 구현해야한다.
String
과 Integer
클래스에서는 equals()
메서드가 이미 재정의 되어 있으므로 이를 이용하여 Student
클래스의 equals()
메서드를 오버라이딩 해보자.
우선 String과 Integer클래스에서 어떻게 equals가 작동하는지 알아보자.
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
System.out.println(str1.equals(str2));
Integer num1 = 100;
Integer num2 = 100;
System.out.println(num1.equals(num2));
}
/*출력결과
true
true
*/
str1
과 str2
는 그 내용은 같지만 인스턴스의 주소가 다르다. 하지만 equals
메서드를 이용해 비교하면 동일하다는 결과가 나온다. 이를 통해 String형에서의 equals()는 두 대상의 내용이 같으면 같다고 판단한다는 것을 알 수 있다.
num1
과 num
2도 마찬가지로 Integer형에서 인스턴스의 주소값이 아니라 변수에 할당된 값이 같으면 같다고 판단된다.
이제 이를 이용하여 Student클래스의 equals()를 아래와 같이 재정의 할수 있을 것이다.
@Override
public boolean equals(Object obj) {
if (obj instanceof Student) { //비교대상이 Student형이면
Student std = (Student)obj;
if(this.studentId == std.studentId)
return true; //학번이 같으면 같은 사람
else
return false;
}
return false;
}