Java에서 객체를 비교할 때 의미 검사 를 수행하여 객체 의 유형을 비교하고 상태 를 식별 합니다.
- 자체 (동일한 인스턴스)
- 자체 (복제 또는 재구성 된 사본)
- 다른 유형의 다른 개체
- 같은 유형의 다른 개체
null
규칙 :
- 대칭 :
a.equals(b) == b.equals(a)
equals()
항상 얻을 수 없다 true
거나 false
, 그러나 결코 NullpointerException
, ClassCastException
또는 다른 throw 가능 객체
비교:
- 유형 검사 : 두 인스턴스가 동일한 유형 이어야 합니다. 즉, 실제 클래스가 동일한 지 비교해야합니다. 개발자
instanceof
가 유형 비교에 사용할 때 (하위 클래스가없는 한만 작동하며 A extends B -> a instanceof b != b instanceof a)
.
- 상태 식별의 의미 검사 : 인스턴스가 식별되는 상태를 이해했는지 확인하십시오. 사람은 사회 보장 번호로 식별 할 수 있지만 머리 색깔 (염색 가능), 이름 (변경 가능) 또는 나이 (항상 변경됨)로는 식별 할 수 없습니다. 값 개체와 만 전체 상태 (모든 비 일시적 필드)를 비교해야하며 그렇지 않으면 인스턴스를 식별하는 항목 만 확인합니다.
귀하의 경우 Person
클래스 :
public boolean equals(Object obj) {
// same instance
if (obj == this) {
return true;
}
// null
if (obj == null) {
return false;
}
// type
if (!getClass().equals(obj.getClass())) {
return false;
}
// cast and compare state
Person other = (Person) obj;
return Objects.equals(name, other.name) && Objects.equals(age, other.age);
}
재사용 가능한 일반 유틸리티 클래스 :
public final class Equals {
private Equals() {
// private constructor, no instances allowed
}
/**
* Convenience equals implementation, does the object equality, null and type checking, and comparison of the identifying state
*
* @param instance object instance (where the equals() is implemented)
* @param other other instance to compare to
* @param stateAccessors stateAccessors for state to compare, optional
* @param <T> instance type
* @return true when equals, false otherwise
*/
public static <T> boolean as(T instance, Object other, Function<? super T, Object>... stateAccessors) {
if (instance == null) {
return other == null;
}
if (instance == other) {
return true;
}
if (other == null) {
return false;
}
if (!instance.getClass().equals(other.getClass())) {
return false;
}
if (stateAccessors == null) {
return true;
}
return Stream.of(stateAccessors).allMatch(s -> Objects.equals(s.apply(instance), s.apply((T) other)));
}
}
당신을 위해 Person
클래스,이 유틸리티 클래스를 사용하여 :
public boolean equals(Object obj) {
return Equals.as(this, obj, t -> t.name, t -> t.age);
}