ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Effective Java 모든 객체의 공통 메서드
    java 2021. 5. 25. 12:01

    equals()는 일반 규약을 지켜 재정의하라

    equals()를 오버라이딩하지 않는다면 위처럼 모든 클래스가 위 equals()를 상속받는다. == 비교로써 두 객체 인스턴스가 물리적으로 동일한 객체인 경우만 true를 반환한다. equals()를 오버라이딩할 때는 사이드이팩트가 많아서 주의를 기울이거나 아예 오버라이딩하지 않길 권장한다. 그래도 물리적인 비교가 아닌 논리적 비교가 필요한 경우가 있으니 주의사항을 알아보자.

     

    반사성(reflexivity)

    x.equals(x)는 반드시 true를 반환하여야 함을 말한다. 의도적으로 false를 반환하지 않는 한 이 규약은 지켜질 거고 직관적으로 이해해기 어렵지 않다.

     

    대칭성(symmetry)

    객체를 비교할 때 교환법칙이 성립해야함을 의미한다. 즉, x.equals(y) == y.equals(x) 여야 한다는 거다. 이 규약 또한 위배하려고 하지 않는 한 굳이 위배할 일은 없을 것 같다.(책에 나온 예제도 내가 볼때는 억지성이 있다.)

     

    추이성(transitivity)

    x.equals(y) == true && y.equals(z) == true => x.equals(z) == true여야 한다는 거다. 상속관계의 equals() 오버라이딩에서 대칭성을 지키기 위해 코드를 작성하다보면 추이성을 어길 가능성이 있다.

    Engineer에서 Job을 상속하고 새로운 필드 position을 추가했다. 만약 Engineer에서 equals()를 오버라이딩하지 않았다면 position이 다른 Engineer라도 equals()를 true로 반환하게 되니 오버라이딩은 필수다. 다만, 위와 같이 재정의하게 된다면 대칭성을 어기게 된다. 

     

    대칭성을 지키도록 오버라이딩했다. 이때는 추이성을 어기게 된다. 하나의 Job과 둘의 Engineer를 생각해보면 된다. 다만, 이런 상황도 크게 고려할 대상은 아닌 것 같다. 클래스를 상속하고 새로운 필드를 추가하는 경우가 드물다. 주로 객체 합성을 이용해 논리적인 새로운 타입을 만드는 경우가 많다. 

     

    일관성(consistency)

    equals()를 수행하고 따로 값이 변경되지 않는다면 계속 같은 결과를 반환해야 한다는 내용인데 따로 설명할 필요 없는 듯하다.

     

    equals()를 오버라이딩 하면 hashCode()도 오버라이딩 하자

    HashMap에서 put하는 과정을 일부만 캡쳐한 내용이다. key의 hashCode()를 이용해 먼저 테이블에서 key의 위치를 찾는다. 이후 key.equals()를 호출해 동일 객체인지 확인하는 것이다. 즉, 레퍼런스가 다른 두객체를 논리적으로 같다고 하기 위해 equals()를 오버라이딩했다면 반드시 hashCode()도 오버라이딩해야 원하는 대로 hashCode()를 이용한 컬렉션 프레임워크가 동작한다.

     

    hashCode() 오버라이딩 최적화

    공간을 고려해 최대한 해시충돌이 덜 나게끔 설계하는 게 좋다. 다만, 이론적인 내용이고 깊게 생각하면 밑도 끝도 없으므로 String의 오버라이딩 부분을 참고하는 정도로 넘어가자.

     

     

    toString()을 항상 오버라이딩하라

    기본 toString()인 경우 클래스 명과 해시코드값을 16진수로 표현한 값을 문자열로 반환한다. 대부분의 경우 쓸모없는 정보이고 디버깅에 도움이 안된다. 이때 객체를 명확히 표현할 수 있는 문자열로 toString()값을 오버라이딩하라는 의미다. 다만, 경험상 toString()을 오버라이딩하여 큰 도움을 얻은 적이 없고 실제로 잘 하진 않는다. 나중에 필요하면 하겠지?

     

     

    'java' 카테고리의 다른 글

    Optional 정리  (0) 2021.05.28
    Inner class와 static 조합  (0) 2021.05.27
    람다 정리 및 예시  (0) 2021.05.19
    Thread 정리  (0) 2021.05.11
    애너테이션 정리  (0) 2021.05.11

    댓글

Designed by Tistory.