Object
는 동등성 비교를 위한 equals()
메서드를 제공.
- 동일성(Identity) :
==
연산자를 사용해서 두 객체의 참조가 동일한 객체를 가리키고 있는지 확인- 동등성(Equality) :
equals()
메서드를 사용해서 두 객체가 논리적으로 동등한지 확인
public boolean equals(Object obj) {
return (this == obj)
}
Object
의 euqals()
메서드를 확인해보면 기본적으로 동일성==
비교를 하고 있다.
//equals() 예제 User 객체는 equals() 메서드를 Override 하지 않음
User user1 = new User("user");
User user2 = new User("user");
user1.equals(user2); // false
내가 원한 결과는 둘 다 user
라는 이름의 User 객체이기 때문에 논리적으로 같다는 true
를 원했지만... equals()
는 기본적으로 ==
비교를 하고 있기 때문에 false
를 반환한다.
이 두 객체가 논리적으로 동등한지 파악하기 위해선 사용자가 직접 equals()
객체를 재정의해서 사용해야 한다.
쉽게 말해서 동일성
==
비교는 물리적으로 같은 메모리에 있는 객체 인스턴스인지 참조값을 확인하는 것이고 동등성equals
비교는 사람이 생각하는 논리적인 기준에 맞춰 비교하는 것이다.
컴퓨터가 봤을때==
와 사람이 봤을때equals
라고 생각하면 될 것 같다.
우선 간단하게 구현을 해보자
//User 클래스
public class User {
private String id;
public User(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
UserV2 user = (UserV2) obj;
return id.euqals(user.id);
}
}
id의 값이 String 이기 때문에 ==
이 아닌 equals()
를 사용했다.
이 코드는 아주 간단하게 넘어온 객체를 UserV2 로 다운캐스팅하고 id 값이 같은지 확인하고 있다.
//간단 equals() 예제 User 객체는 equals() 메서드를 Override 했다.
User user1 = new User("user");
User user2 = new User("user");
user1.equals(user2); // true
이제는 내가 원하는대로 true
가 반환되는걸 볼 수 있다.
하지만 equals()
가 너무 간단하게 구현되었다. 실제로 정확하게 동작하려면 몇가지 규칙을 지켜서 구현해야 하기 때문에 equals()
를 구현하는 것은 생각보다 쉽지 않다고 한다. 우선 코드를 보자
//변경 - 정확한 equals 구현, IDE 자동 생성
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id);
}
한눈에 봐도 아까 코드랑은 확실히 다르다. this == o
와 null
, getClass()
도 체크하고 있다.
equals() 메서드를 구현할 때 지켜야 하는 규칙
- 반사성(Reflexivity): 객체는 자기 자신과 동등해야 한다. ( x.equals(x) 는 항상 true ).
- 대칭성(Symmetry): 두 객체가 서로에 대해 동일하다고 판단하면, 이는 양방향으로 동일해야 한다.
( x.equals(y) 가 true 이면 y.equals(x) 도 true ).- 추이성(Transitivity): 만약 한 객체가 두 번째 객체와 동일하고, 두 번째 객체가 세 번째 객체와 동일하다면, 첫번째 객체는 세 번째 객체와도 동일해야 한다.
- 일관성(Consistency): 두 객체의 상태가 변경되지 않는 한, equals() 메소드는 항상 동일한 값을 반환해야 한다.
- null에 대한 비교: 모든 객체는 null 과 비교했을 때 false 를 반환해야 한다.
물론 위와 같은 규칙을 외워서 equals()
메서드를 작성하는 일은 거의 없다고 한다. 이런 규칙이 있다는 것만 알아두고 IDE에서 제공하는 equals()
를 적절히 사용하면 된다.
hashCode()
도 equals()
와 함께 사용하는데 이는 컬렉션 프레임워크 에서 더 자세히 다룬다고 한다.
- 김영한의 실전 자바 - 중급 1편을 공부하면서 작성했습니다.