제육's 휘발성 코딩
article thumbnail
반응형

toString을 항상 재정의하라

Object의 기본 메서드 중 toString은 재정의하지 않으면 phone@adbbd처럼 단순히 클래스명@해시코드를 표현한다. toString의 규약은 모든 하위 클래스에서 이 메서드를 재정의하라이다.

 

toString 메서드는 객체를 println, printf, +, assert, 디버거 등 을 출력할 때 자동으로 호출된다. 즉, 직접 호출하지 않아도 사용되는 경우가 많다. 따라서 재정의는 필수적이며, 재정의 시에 객체가 가진 주요 정보를 모두 반환하는 것이 올바르다.

 

/**  
* Returns a string representation of this collection.  The string
* representation consists of a list of the collection's elements in the
* order they are returned by its iterator, enclosed in square brackets
* ({@code "[]"}).  Adjacent elements are separated by the characters
* {@code ", "} (comma and space).  Elements are converted to strings as
* by {@link String#valueOf(Object)}.
*
* @return a string representation of this collection
*/
public String toString() {
    Iterator<E> it = iterator();
    if (! it.hasNext())
        return "[]";

    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (;;) {
        E e = it.next();
        sb.append(e == this ? "(this Collection)" : e);
        if (! it.hasNext())
            return sb.append(']').toString();
        sb.append(',').append(' ');
    }
}
  • 컬렉션의 toString은 상위 타입인 AbstractCollection<E> 추상 클래스에서 선언된 메서드대로 출력 된다. 우리가 단순히 println(list) 등을 했을 때 값이 출력되는 부분이 해당 메서드 정의 덕분이다.

 

포맷 문서화 여부를 결정하자

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);
 }

 

포맷을 명시하지 않은 예

/**
 * 이 약물에 관한 대락적인 설명을 반환한다.
 * 다음은 이 설명의 일반적인 형태이나,
 * 상세 형식은 정해지지 않았으며 향후 변경될 수 있다.
 *
 * "[약물 #9: 유형=사랑, 냄새=테레빈유, 겉모습=먹물]"
 */
 @Override
 public String toString() { ... }

 

반환 값의 정보를 API로 제공하자

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

예를 들어 PhoneNumber 클래스는 필요한 정보인 지역 코드, 프리픽스, 가입자 번호용 접근자를 제공해야 한다. 그렇지 않으면 프로그래머가 반환 값을 직접 파싱해야 한다.

 

결론

상위 클래스에서 알맞게 재정의 되지 않은 모든 구현체 클래스에서 Object의 toString을 재정의하자.

반응형
profile

제육's 휘발성 코딩

@sasca37

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요! 맞구독은 언제나 환영입니다^^