toString을 항상 재정의하라 - Effective Java[12]
🔗 모든 하위 클래스에서 toString 메소드를 항상 재정의하라.
Object의 기본 toString 메소드는 우리가 작성한 클래스에 적합한 문자열을 반환하는 경우는 거의 없다.
이 메소드는 단순히 클래스_이름@16진수로_표시한_해시코드를 반환할 뿐이다.
toString의 일반 규약에 따르면 ‘간결하면서 사람이 읽기 쉬운 형태의 유익한 정보’를 반환해야 한다.
또한 toString의 규약은 “모든 하위 클래스에서 이 메소드를 재정의하라”고 한다.
toString을 잘 구현한 클래스는 사용하기에 훨씬 즐겁고, 그 클래스를 사용한 시스템은 디버깅하기 쉽다.
💎toString 작성 시 주의 할 점
- toString은 그 객체가 가진 주요 정보 모두를 반환하는게 좋다.
- 하지만 객체가 거대하거나 객체의 상태가 문자열로 표현하기에 적합하지 않다면 무리가 있다. 이런 상황이라면 “맨해튼 거주자 전화번호부 (총 1487536개)”나 Thread[main,5,main]”과 같은 요약 정보를 담아야 한다. 이상적으로는 스스로를 완벽히 설명하는 문자열이어야한다.
-
반환 값의 포맷을 문서화할지 정해야 한다. 전화번호나 행렬 같은 값 클래스라면 문서화하기를 권한다. 포맷을 명시하면 그 객체는 표준적이고, 명확하고, 사람이 읽을 수 있게 된다. 따라서 그 값 그대로 입출력에 사용하거나 CSV 파일처럼 사람이 읽을 수 있는 데이터 객체로 저장할 수 도 있다.
-
포맷을 명시하든 아니든 개발자의 의도는 명확히 밝혀야 한다.
포맷을 명시하려면 아주 정확하게 해야한다. 다음의 toString 메소드를 보자.
123456789101112131415161718192021// 포맷을 명시하기로 한 경우/*** 이 전화번호의 문자열 표현을 반환한다.* 이 문자열은 "XXX-YYY-ZZZZ" 형태의 12글자로 구성된다.* XXX는 지역 코드, YYY는 프리픽스, ZZZZ는 가입자 번호다.* 각각의 대문자는 10진수 숫자 하나를 나타낸다.** 전화번호의 각 부분의 값이 너무 작아서 자릿수를 채울 수 없다면,* 앞에서부터 0으로 채워나간다. 예컨대 가입자 번호가 123이라면* 전화번호의 마지막 네 문자는 "0123"이 된다.*/@Override public String toString() {return String.format("%03d-%03d-%04d",areaCode, prefix, lineNum);}// 포맷을 명시하지 않기로 한 경우/*** 상세형식은 정해지지 않았으며 향후 변경될 수 있다.*/@Override public String toString() {...}cs
만약 이러한 설명을 읽고도 이 포맷에 맞춰 코딩하거나 특정 값을 빼내어 영구 저장한 프로그래머 는 나중에 포맷이 바뀌어 피해를 입어도 자기 자신을 탓할 수 밖에 없을 것이다.
-
toString이 반환한 값에 포함된 정보를 얻어올 수 있는 API를 제공하자.
-
예를들어 PhoneNumber 클래스는 areaCode, prefix, lineNum 접근자를 제공해야 한다.
그렇지 않으면 이 정보가 필요한 프로그래머는 toString의 반환 값을 파싱할 수 밖에 없다.
성능이나빠지고, 필요하지도 않은 작업이다.
-
모든 구체 클래스에서 Object의 toString을 재정의하자. 상위 클래스에서 이미 알맞게 재정의한 경우는 예외다. toString을 재정의한 클래스는 사용하기도 즐겁고 그 클래스를 사용한 시스템을 디버깅하기 쉽게 해준다. toString은 해당 객체에 관한 명확하고 유용한 정보를 읽기 좋은 형태로 반환해야한다.
참조 - 이펙티브 자바 3/E - 조슈아 블로크
Comments