티스토리 뷰

* 이펙티브 자바 2/E를 읽고 공부하기 위해 기록한 게시글입니다.

 

모든 자바 클래스의 최고 조상 클래스인 Object 클래스는 객체 생성이 가능한 클래스지만, 기본적으로는 계승해서 사용하도록 만들어진 클래스이다.

- Object에 정의된 비-final(final이 아닌) 메서드: equals, hashCode, toString, clone 등..

-> 명시적인 일반 규약이 존재하고, 오버라이드 해서 사용하도록 설계된 메서드들이다. 위 메서드를 재정의하는 클래스는 해당 일반 규약을 따라야 한다.

 

 

8. equals를 재정의할 때는 일반 규약을 따르라.

equals 메서드는 언제 재정의 해서 사용해야 하는가?

1. 객체 동일성(Object equality)가 아닌, 논리적 동일성(Logical equality)의 개념을 지원하는 클래스일 때

2. 상위 클래스의 equals가 하위 클래스의 필요를 충족시키지 못할 때.

 

equals 메서드는 따로 재정의를 하지 않으면, 객체의 참조값을 비교해 객체 동일성만을 비교하게 된다

* 싱글톤 객체나 Enum 자료형은 각각 최대 하나씩만 존재하기 때문에 굳이 equals 재정의를 할 필요가 없다.

 

=======

[동일성 vs 동등성]

동일성(identical): 두개의 오브젝트가 완전히 동일함. (== 비교)

동등성(equivalent): 동일한 정보를 담고 있음 (equals() 비교)

- 동일한 오브젝트는 동등하다. 하지만 동등한 오브젝트가 동일하지는 않다.

- 두 오브젝트가 서로 동일하다면 사실 오브젝트는 하나만 존재하고 있는것이다. 같은 주소값을 참조하고 있는 것.

=======

 

equals 메서드를 재정의할 때 준수해야 하는 일반 유약(General contract)은 다음과 같다

equals 메서드는 동치관계(equivalence relation)을 구현한다

 

 

* 동치관계란, 아래와 같은 관계를 뜯한다

반사성(reflexive): null이 아닌 참조 x가 있을 때 x.equals(x)는 true여야 한다

대칭성(symmetric): null이 아닌 참조 x, y가 있을 때 x.equals(y)는 y.equals(x)가 true일 때만 true여야 한다,

추이성(transitive): null이 아닌 참조 x,y,z가 있을 때, x.equals(y)도 true고, y.equals(z)도 true이면 x.equals(z)도 true.

일관성(consistent): null이 아닌 참조 x,y가 있을 때, equals를 통해 비교되는 정보에 변화가 없다면 x.equals(y) 의 결과는 호출 횟수에 상관없이 동일해야 한다

+ null이 아닌 참조 x에 대해 x.equals(null)은 false여야 한다.

 

1. 반사성

모든 객체는 자기 자신과 같아야한다. 당연한 이야기.

 

2. 대칭성

두 객체에게 서로 같은지 물으면 같은 답이 나와야 한다

 

3. 추이성

= 삼단논법 (A = B고 B = C면 A = C이다)

 

4. 일관성

일단 같다고 판정된 객체들은 나중에 변경되지 않는 한 계속 같아야한다.

 

5. 모든 객체는 null과 동치관계에 있지 않아야 한다.

 

 

그래서 어떻게 하면 되는데?

>>>> IDE에서 자동으로 만들어주는거 그냥 갖다 쓰자 

그래도 구성 순서를 알아보면 다음과 같다.

 

1. 가장 먼저 == 연산자를 이용해 equals 인자가 자기 자신인지 검사해라

2. instanceof 연산자를 사용하여 인자의 자료형이 정확한지 검사해라

-> instanceof 대신 getClass 메서드를 사용해서 기존 클래스를 확장하고 새로운 값 컴포넌트를 추가해도 equals 규약을 지킬 수 있는 스타일이 등장 (IDE 기본) <- 리스코프 치환 원칙을 어긴다는 문제점이 발생. 논쟁이 있는 사항.

(++ instanceof 사용을 지양하라는 이야기도 많다. (링크) 객체지향의 원칙을 어긴다는 이유.)

 

3. equals의 인자를 정확한 자료형으로 변환해라

4. 필드 각각이 인자로 주어진 객체의 해당 필드와 일치하는지 확인해라

5. equals 메서드 구현이 끝났다면 대칭성, 추이성, 일관성의 속성을 만족하는지 검토해라

 

    @Override
    public boolean equals(Object o) {
        if (this == o) return true; // 1번
        if (o == null || getClass() != o.getClass()) return false; // 2번
        User user = (User) o; // 3번
        return Objects.equals(getId(), user.getId()) 
            && Objects.equals(getName(), user.getName()) 
            && Objects.equals(getTel(), user.getTel()); // 4번
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId(), getName(), getTel());
    }

 

* 주의사항

1. equals 메서드를 구현할 때에는 hashCode도 재정의 해라

2. equals 메서드의 인자형을 Object 이외의 것으로 바꾸지 마라

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함