12. toString 을 항상 재정의하라
#
toString 일반 규약toString 일반 규약
- 간결하면서 사람이 읽기 쉬운 형태의 유익한 정보를 반환해야 한다.
- 모든 하위 클래스에서 이 메서드를 재정의 하라
#
Object 의 toString 메서드가 기본적으로 반환하는 문자열클래스_이름@16진수로_표시한_해시코드
- PhoneNumber@addbd
- 간결하지만 전화번호를 직접알려주는 형태가 훨씬 더 유익하다.
#
잘 구현된 toString 메서드 클래스의 장점- 사용이 편하다
- 시스템 디버깅이 쉬워진다.
#
toString 의 자동 호출 문맥- 콘솔로 객체를 확인할 때
System.out.println()
System.out.print()
- 객체에 문자열을 연결
(SomeObject + "")
assert
구문 사용 시
- 디버거가 객체를 출력할 때
- 작성한 객체를 참조하는 컴포넌트가 오류 메시지를 로깅할 때 자동으로 호출됨
#
toString 에 적합한 내용- 그 객체가 가진 주요 정보를 모두 반환하는 것이 좋다.
- 거대한 객체 or 객체 상태가 문자열 표현으로 부적합
- 요약 정보를 담는다.
- 맨해튼 거주자 전화번호부(총 1233434324개)
- Thread[main, 5, main]
#
toString 반환값 포맷 문서화#
장점과 특징그 객체는 표준적, 명확함, 사람이 읽을 수 있는 특징을 가진다.
- 전화번호나 행렬 같은 값 클래스 → 문서화 권장
- 값 그대로 입출력에 사용한다
- CSV 파일처럼 사람이 읽을 수 있는 데이터 객체로 저장한다
- 포맷에 맞는 문자열과 객체를 상호전환할 수 있는 정적 팩터리나 생성자를 함께 제공해 주면 좋다. ??
#
단점포맷을 한번 명시하면(그 클래스가 많이 쓰인다면) 평생 포맷에 얽매인다
- 이를 사용하는 프로그래머들이 그 포맷에 맞춰 다음과 같은 행위를 할 것이기 때문.
- 파싱
- 새로운 객체 생성
- 영속 데이터로 저장
포맷을 명시하지 않는다면 향후 릴리스에서 정보를 더 넣거나 포맷을 개선할 수 있는 유연성을 얻게 된다.
포맷을 명시하든 아니든 의도는 명확히 밝혀야 한다. 설명을 읽고서도 위와 같은 행위를 하여 피해를 입는다면 사용한 프로그래머의 잘못이다.
단, 포맷을 명시하려면 아주 정확하게 해야 한다.
포맷 명시 여부과 상관 없이 toString 이 반환한 값에 포함된 정보를 얻어올 수 있는 API 를 제공하자
- 클래스 필드에 대한 정보가 필요한 프로그래머는 toString 의 값을 파싱해야 한다.
→ 성능저하, 불필요한 작업 → 향후 포맷을 바꾸면 시스템이 망가진다.
caution
접근자를 제공하지 않으면, 변경될 수 있다고 문서화를 해도 그 포맷이 사실상 준-표준 API 나 다름없다.
#
toString 을 재정의 하지 않아도 되는 타입#
toString 을 재정의 해야하는 타입하위 클래스들이 공유해야 할 문자열 표현이 있는 추상클래스 ??
- 대다수의 컬렉션 구현체는 추상 컬렉션 클래스들의 toString 메서드를 상속해서 쓴다.
#
toString 자동생성AutoValue
프레임워크로는 클래스의 의미까지 파악하기 어렵다.- 자동생성에 적합하지 않는 타입
- PhoneNumber 은 표준체계가 있다.
- 자동생성에 적합하지 않더라도 객체의 값에 관해 아무것도 알려주지 않는 Object 의 toString 보다는 자동생성하는 것이 낫다.