Search

Item 12. toString을 항상 재정의하라

생성일
2023/07/27 10:36
챕터
3장 - 모든 객체의 공통 메서드

toString을 사용해야하는 이유

Object 클래스의 기본 toString 메서드로 우리가 작성한 클래스를 변환하면 PhoneNumber@adbbd처럼 단순히 클래스이름@16진수해시코드 형태를 반환한다.
toString을 재정의하여 잘 구현하면 클래스를 사용하기에 훨씬 용이하고, 디버깅하기 쉬워진다.

toString 재정의하기

toString을 재정의할 때는 해당 클래스가 가진 주요 정보들을 모두 반환하는 것이 좋다. 이상적으로는 해당 객체를 완벽히 설명하는 문자열이어야 한다.
toString을 구현할 때는 반환값의 포맷을 문서화 할 지 정해야하는데, 포맷을 명시하면 그 객체는 표준적이고 명확하고 사람이 읽을 수 있다.
포맷을 명시한다면, 명시되어있는 포맷의 문자열을 받아 해당 클래스의 인스턴스를 생성할 수 있는 정적 팩터리나 생성자를 제공해주는 것이 좋다.
toString의 포맷을 명시하든 아니든, 아래의 예시처럼 의도를 명확히 밝히는 것이 좋다.
포맷을 명시하는 경우
/** * 이 전화번호의 문자열 표현을 반환한다. * 이 문자열은 "XXX-YYY-ZZZZ" 형태의 12글자로 구성된다. * XXX는 지역 코드, YYY는 프리픽스, ZZZZ는 가입자 번호다. * 각각의 대문자는 10진수 숫자 하나를 나타낸다. * * 전화번호의 각 부분의 값이 너무 작아서 자릿수를 채울 수 없다면, * 앞에서부터 0으로 채워나간다. 예컨대 가입자 번호가 123이라면 * 전화번호의 마지막 네 문자는 "0123"이 된다. */ @Override public String toString() { return String.format("%03d-%03d-%04d", areaCode, prefix, lineNum); }
Java
복사
포맷을 명시하지 않는 경우
/** * 이 약물에 관한 대략적인 설명을 반환한다. * 다음은 이 설명의 일반적인 형태지만, * 상세 형식은 정해져있지 않으며 향후 변경될 수 있다. * * "[약물 #9: 유형=사랑, 냄새=테레빈유, 겉모습=먹물]" */ @Override public String toString() { ... }
Java
복사
toString이 반환한 값에 포함된 정보를 얻어올 수 있는 API(접근자)를 제공하자.
위의 PhoneNumber 클래스를 예시로 들면, 지역코드, 프리픽스, 가입자 번호용 접근자를 제공해야 한다.
Integer getAreadCode() { return areaCode; } Integer getPrefix() { return prefix; } Integer getLineNum() { return lineNum; }
Java
복사
이와 같은 API를 제공하지 않으면 사용자가 toString을 직접 파싱해야하고, 그로 인해 성능이 저하되고 불필요한 작업을 수행해야한다.
정적 유틸리티 클래스와 대부분의 열거 타입은 자바가 이미 완벽한 toString을 제공하기 때문에 toString을 재정의해서 제공할 필요가 없다.
하위 클래스들이 공유해야할 문자열 표현이 있는 추상 클래스의 경우에는 toString을 재정의 해주어야 한다.