들어가기 전
이 글은 인프런 백기선님의 강의를 복습하며 작성한 글입니다.
핵심 정리
- toString은 간결하면서 사람이 읽기 쉬운 형태의 유익한 정보를 반환해야한다.
- Object의 toString은 클래스이름@16진수로 표시한 해시 코드 (기본 값)
- 객체가 가진 정보 중 공개해도 되는 정보만 표시하는 것이 좋다.
- 값 클래스라면 포멧을 문서에 명시하는 것이 좋으며, 해당 포멧으로 객체를 생성할 수 있는 정적 팩터리나 생성자를 제공하는 것이 좋다
- toString이 반환한 값에 포함된 정보를 얻어올 수 있는 API를 제공하는 것이 좋다.
- toString()은 공개된 정보이기 때문에 각각을 얻어올 수 있는 Getter 메서드를 제공해주는 것이 좋다.
- 경우에 따라 롬복 또는 IDE를 사용하지 않는게 적절할 수 있다.
- 원하는 포멧이 있을 때 사용하지 않는게 적절할 수 있음. 이 때는 직접 구현하면 됨.
toString은 객체를 print 했을 때, 대신 호출되도록 작성되어있다. 대부분 객체가 가진 정보를 보기 위해서 찍어보기 때문에 toString()은 사람이 읽기 쉬운 형티의 유익한 정보를 제공해줘야한다. Object의 toString()은 기본적으로 클래스이름@16진수를 출력해준다. 이 정보 자체는 크게 쓸모가 없다. 만약 toString()을 자주 호출해야 할 클래스라면, 적절한 정보를 제공할 수 있도록 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);
}
// 포멧을 호출할 수 있는 정적 팩토리 메서드 추가하기.
public static PhoneNumber of(String phoneNumberString) {
String[] split = phoneNumberString.split("-");
PhoneNumber phoneNumber = new PhoneNumber(
Short.parseShort(split[0]),
Short.parseShort(split[1]),
Short.parseShort(split[2]));
return phoneNumber;
}
toString이 반환한 값에 포함된 정보를 얻어올 수 있는 API를 제공하는 것이 좋다.
toString()은 public API다. 따라서 toString()을 통해서 노출되는 정보는 공개 정보이며, 공개 정보는 외부로 노출할 수 있는 정보만 선택해야한다. toString()을 통해서 이미 제공한 정보이기 때문에 각 정보에 대한 Getter를 제공하는 것도 좋은 선택이 될 수 있다.
이미 정보는 공개되어 있는데, 각 정보를 선택적으로 가져다 쓰고 싶을 수 있기 때문에 이 때 각 정보에 대한 Getter()를 제공하는 것이다.
@Override
public String toString() {
return String.format("%03d-%03d-%04d",
areaCode, prefix, lineNum);
}
// 정보 제공
public short getAreaCode() {
return areaCode;
}
// 정보 제공
public short getPrefix() {
return prefix;
}
// 정보 제공
public short getLineNum() {
return lineNum;
}
경우에 따라 롬복 또는 IDE를 사용하지 않는게 적절할 수 있다.
toString()으로 출력하고 싶은 포멧이 있는 경우라면 롬복 / IDE가 적절하지 않을 수 있다. 이 경우에는 toString()을 직접 구현해서 사용해야 한다. 아래에서 확인할 수 있듯이 인텔리제이가 제공하는 toString()은 우리가 원하는 것과는 다른 형태다.
// 우리가 원하는 포멧
@Override public String toString() {
return String.format("%03d-%03d-%04d",
areaCode, prefix, lineNum);
}
// 인텔리제이 제공
@Override
public String toString() {
return "PhoneNumber{" +
"areaCode=" + areaCode +
", prefix=" + prefix +
", lineNum=" + lineNum +
'}';
}
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
Effective Java : 아이템 11. equals를 재정의하면, hashCode도 재정의하라. (0) | 2023.05.14 |
---|---|
Effective Java : 아이템10. 완벽공략 (1) | 2023.05.14 |
Effective Java : 아이템10. equals는 일반 규약을 지켜 재정의하라 (핵심 정리) (0) | 2023.05.13 |
Effective Java : 아이템33. 한정적 타입 토큰 (0) | 2023.04.27 |
Effective Java : 아이템33. 타입 안전 이종 컨테이너를 고려하라 (1) | 2023.04.20 |