[effective java] 3장 item12 - toString을 항상 재정의하라

2019-02-11

기본 toString메서드는 단순히 클래스_이름@16진수로_표현한_해시코드 를 반환한다.

간결하면서 사람이 읽기 쉬운 형태의 유익한 정보 를 반환한다.

가 toString의 일반 규약이며 모든 하위 클래스에서 이 메서드를 재정의하라고 한다.

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

toString메서드는 객체를 println, printf, 문자열 연결 연산자(+), assert 구문에 넘길 때, 혹은 디버거가 객체를 출력할 때 자동으로 불린다. (어딘가에서 쓰인다!)

// PhoneNumber용 toString을 제대로 재정의했다면 이 코드만으로 충분하다.
System.out.println(phoneNumber + "에 연결할 수 없습니다.");

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

toString의 반환값의 포맷을 문서화할지 정해야 한다.

포맷을 명시하기로 했다면, 명시한 포맷에 맞는 문자열과 객체를 상호 전환할 수 있는 정적 팩터리나 생성자를 함께 제공해주면 좋다.(ex 값 클래스 BigInteger, BigDecimal와 대부분의 기본 타입 클래스)

장/단점은 있다. 그러나 포맷을 명시하든 아니든 의도는 명확히 밝혀야한다.

포맷 명시 여부와 상관없이 toString이 반환한 값에 포함된 정보를 얻어올 수 있는 API를 제공하자.

접근자를 제공하지 않으면 변경될 수 있다고 문서화했더라도 그 포맷이 사실상 준-표준 API나 다름없어진다.

마지막으로…

정적 유틸리티 클래스(아이템4)는 toString을 제공할 이유가 없다. 대부분의 열거타입(아이템34)도 이미 완벽한 toString이 제공되니 재정의 하지 않아도 된다.

하지만 하위 클래스들이 공유해야 할 문자열 표현이있는 추상클래스라면 재정의해줘야 한다. (컬렉션 구현체는 추상 컬렉션 클래스들의 toString메서드를 상속해 쓴다.)

AutoValue 프레임 워크는 toString도 생성해준다. 아무것도 알려주지 않는 Object toString보다 훨씬 유용하다.