equals()
- 클래스 Obejct에 대한 equals 메소드는 객체에 대해 등가 관계를 구현한다. 즉 null이 아닌 참조 값 x 및 y가 동일한 객체를 참조하는 경우에만 true를 반환한다.
class Person {
private int age;
private String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
}
public static void main(String[] args) {
Parent person = new Parent(19, "lala");
Parent person1 = new Parent(19, "lala");
System.out.println(person.equals(person1)); //false
}
person.equals(person1) 왜 결과가 false일까?
Obejct의 equals 메소드 정의를 보면 다음과 같다
public boolean equals(Object obj) {
return (this == obj);
}
단순히 Object의 ==로 비교하는 것을 확인할 수 있다. “값"을 비교하는 것이 아니라 “주소값” 즉 hashCode를 비교하고 있는 것이다.
이 문제를 해결하기 위해서는 equals()를 Override해야 한다.
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
if (this == obj) {
System.out.println("Object Same");
return true;
}
Person that = (Person) obj;
if (this.name == null && that.name != null) {
return false;
}
if (this.age == that.age && this.name.equals(that.name)) {
System.out.println("Object Value Same");
return true;
}
return false;
}
equals() 메서드를 overriding할 때 반드시 지켜야할 조건
- 재귀: null이 아닌 x라는 객체의 x.equals(x) 결과는 항상 true여야만 한다.
- 대칭: null이 아닌 x와 y객체가 있을 때 y.equals(x)가 true를 리턴했따면, x.equals(y)도 반드시 true를 리턴해야만 한다.
- 타동적: null이 아닌 x,y,z가 있을 때 x.equals(x)가 true를 리턴했다면, y.equals(z)가 true를 리턴할 때 x.equals(z)는 반드시 true를 리턴해야만 한다.
- 일관: null이 아닌 x와 y가 있을 때 객체가 변경되지 않은 상황에서는 몇 번을 호출하더라도 결과가 항상 true이거나 false여야만 한다.
- null과의 비교: null이 아닌 x라는 객체의 x.equals(null) 결과는 항상 false여야만 한다.
hashCode()
- hashCode 메소드는 실행 중에(Runtime) 객체의 유일한 정수 값을 반환한다.
- Object의 hashCode() 메서드는 객체의 메모리 번지를 이용해서 해시코드를 만들어 리턴하기 때문에 객체마다 다른 값들을 가지고 있다.
- 어떠한 객체와 다른 객체의 equals 결과가 true라면 그 둘의 hashCode 값은 반드시 같아야 한다.
- equals가 두 객체를 다르다고 판단했더라도, 두 객체의 hashCode가 서로 다른 값을 반환할 필요는 없다. 단 다른 객체에 대해서는 다른 값을 반환해야 해시 테이블의 성능이 좋아진다.
public static void main(String[] args) {
Person person1 = new Person(18, "kim");
Person person2 = new Person(18, new String("kim"));
Person person3 = person1;
System.out.println(person1.hashCode()); // 151029101
System.out.println(person2.hashCode()); // 234321212
System.out.println(person3.hashCode()); // 234321212
}
위의 코드에 대한 Stack
과 Heap
메모리 할당 구조는 다음과 같다.
'자바' 카테고리의 다른 글
JVM, JDK, JRE, JIT (0) | 2022.07.18 |
---|---|
Call by Value와 Call by Reference (0) | 2022.07.14 |
String의 특징 (0) | 2022.07.14 |