(Effective Java 2/E) 112. Item 10 - Always override toString

Always override toString

  • 2판 제목 : toString은 항상 재정의하라
  • 3판 제목 : toString을 항상 재정의하라

자바의 최상위 객체인 Object가 기본적으로 제공하는 toString 함수는 아래 포맷을 단순히 출력해준다.

1
{CLASS_NAME}@{UNSIGNED_HEXADECIMAL_HASH_CODE}

이 메서드를 꼭 재정의해야하는 규약은 없지만 모든 객체가 가지고 있는 만큼 쓰임새에 따라 클래스를 좀 더 쾌적하게 쓸 수 있게 해준다.

다만 일반적인 규약은 있다. “간결하면서 사람이 읽기 쉬운 형태의 유익한 정보를 반환하라”

가능하다면 toString 함수는 객체 내의 중요 정보를 모두 담아 반환하는 것이 좋다.

하지만 클래스가 거대하거나 객체의 상태가 문자열로 표현하기 적합하지 않다면 요약 정보를 담는 식으로 의도를 명확히 밝히는 게 좋다.

앞서 다루었던 예제를 다시 가져와보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public final class PhoneNumber {
private final short areaCode, prefix, lineNum;

public PhoneNumber(short areaCode, short prefix, short lineNum){
this.areaCode = rangeCheck(areaCode, 999, "지역코드");
this.prefix = rangeCheck(prefix, 999,"프리픽스");
this.lineNum = rangeCheck(lineNum, 9999, "가입자번호");
}
private static short rangeCheck(int val, int max, String arg){
if(val < 0 || val > max){
throw new IllegalArgumentException(arg+" : "+val);
}
return (short) val;
}

@Override
public boolean equals(Object o){
if(o == this)
return true;
if(!(o instanceof PhoneNumber)){
return false;
}

PhoneNumber pn = (PhoneNumber) o;
return pn.lineNum == lineNum && pn.prefix == prefix && pn.areaCode == areaCode;
}

}

PhoneNumber 클래스에 toString을 재정의한다면 아래와 같이 재정의할 수 있다.

1
2
3
@Override public String toString() {
return String.format("(%03d) %03d-%04d", areaCode, prefiex, lineNumber)
}

물론 모든 객체에 권장되는 것은 아니다.

유틸리티 클래스처럼 정적 메서드들로만 구성된 경우나 자바가 기본적으로 잘 출력해주는 열거형의 경우 별도로 재정의하지 않아도 좋다.