티스토리 뷰

(Effective Java) 규칙12. toString을 항상 재정의하라


toString()


  • java.lang.Object 클래스의 toString 메서드는 일반적으로 사용자가 보려는 문자열이 아니다.

    • 클래스 이름 다음에 @기호와 16진수로 표현된 해시 코드가 붙은 문자열 (예: "PhoneNumber@163b91")
  • toString의 일반 규약을 보게 되면 "사람이 읽기 쉽도록 간략하지만 유용한 정보를 제공해야 한다"라고 되어 있다.

    • PhoneNumber@adbbd 보다는 707-867-5309가 훨씬 유익한 정보를 담고 있는 것처럼
    • 더불어 toString 일반 규약에는 "모든 하위 클래스는 이 메서드를 재정의함이 바람직하다"라는 구절도 있음

 

toString()을 재정의 해야 하는 이유


  • toString을 잘 구현한 클래스는 사용하기에 훨씬 즐겁고, 그 클래스를 사용한 시스템을 디버깅하기가 쉽다.

    • 더욱이 toString 메서드는 객체를 출력할 때(println, 디버거 등) 자동으로 불리기 때문에 직접 호출하지 않아도 어딘가에서 쓰임
  • PhoneNumbertoString을 제대로 재정의 했다면 다음 코드만으로 문제를 진단하기에 충분한 메시지를 남길 수 있다.

    System.out.println(phoneNumber + "에 연결할 수 없습니다.");
    • 재정의하지 않았다면 그다지 쓸모가 없는 메시지가 출력됬을 것임

 

명심해야 될 것


  • 실전에서 toString은 그 객체가 가진 주요 정보 모두를 반환하는 게 좋다.

    • 하지만 객체가 거대하거나 객체의 상태를 문자열 로 표현하기 어렵다면, 요약 정보를 담아야 함
      • 예) "맨해튼 거주자 전화번호부(총 12414개)", Thread[main,5,main]
  • toString을 구현할 때면 반환값의 포맷을 문서화할지 정해야 한다.

    • 포맷을 명시하면 그 객체는 표준적이고, 명확하고, 사람이 읽을 수 있게 됨
    • 다만, 포맷을 한번 명시하면 평생 그 포맷에 얽매이게 됨 (이에 의존적인 다른 코드들을 포함)
      • 명시하지 않는다면 향후 릴리스에서 정보를 더 넣거나 개선할 수 있는 유연성을 얻을 수 있음
  • 포맷을 명시하든 아니든 의도는 명확히 밝혀야 한다.

    /**
     * 이 약물에 관한 대략적인 설명을 반환한다.
     * 다음은 이 설명의 일반적인 형태이나, 
     * 상세 형식은 정해지지 않았으며 향후 변경될 수 있다.
     * 
     * "[약물 #9: 유형=사랑, 냄새=테레빈유, 겉모습=먹물]"
     */
    @Override public String toString() { ... }
    • 포맷이 바뀔 여지가 있음을 인지할 수가 있음
  • 정적 유틸리티 클래스는 toString을 제공할 이유가 없고, 대부분의 열거 타입도 자바가 이미 완벽한 toString을 제공하니 따로 재정의하지 않아도 된다.

    • 하지만, 하위 클래스들이 공유해야 할 문자열 표현이 있는 추상 클래스라면 toString을 재정의 해줘야 함
      • 대다수의 컬렉션 구현체는 추상 컬렉션 클래스들의 toString 메서드를 상속해서 씀

 

결론


  • 모든 구체 클래스에서 ObjecttoString을 재정의하자.

    • 단, 상위 클래스에서 알맞게 재정의한 경우는 예외
  • toString을 재정의한 클래스는 그 클래스를 사용한 시스템을 디버깅하게 쉽게 해준다.

  • toString은 해당 객체에 관한 명확하고 유용한 정보를 읽기 좋은 형태로 반환해야 한다.


끝으로

이 글이 도움이 되었다면, Google 광고 한번씩 클릭 부탁 드립니다. 🙏🙏🙏

광고 클릭은 많은 힘이 됩니다!

반응형
댓글