JAVA/Effective Java

[아이템 12] toString을 항상 재정의하라

꾸준함. 2024. 1. 27. 11:16

모든 클래스는 암묵적으로 Object 클래스를 상속하기 때문에 별도로 toString 메서드를 오버라이딩하지 않았을 경우 Object의 toString 메서드를 사용합니다.

문제는 Object의 toString 메서드의 반환값이 아래와 같이  "[패키지를 포함한 클래스명]@[hashCode]" 형태를 띠기 때문에 유의미한 데이터가 아닙니다.

 

Object의 toString

 

 

toString은 보통 로깅할 때 사용되므로 간결하면서 사람이 읽기 쉬운 형태의 정보를 표출해야 하며 라이브러리의 도움을 받거나 직접 정의하는 방식을 선택해야 합니다.

 

toString 구현

저자가 꾸준히 언급하는 구글의 AutoValue 혹은 Lombok의 도움을 통해 toString 구현이 가능합니다.

대부분 케이스에서는 Lombok에서 생성해주는 toString 메서드 혹은 IDE를 통해 생성하는 toString을 사용해도 무방하지만 아래의 케이스에서는 직접 정의하는 것을 권장합니다.

  • item11에서 다루었던 PhoneNumber 클래스와 같이 특정 포맷으로 나타내는 것이 가독성이 더 좋은 경우
  • 보안 정책으로 인해 모든 필드를 다 노출시키면 안 되는 경우
  • 추상 클래스

 

1. 특정 포맷으로 나타내는 것이 가독성이 더 좋은 경우

 

앞서 언급한대로 전화번호의 경우 "010-1234-5678"과 같이 출력하는 것이 Lombok에서 자동 생성하는 toString 메서드보다 훨씬 가독성이 좋습니다.

 

lombok에서 자동으로 생성하는 toString

 

 

 

직접 정의한 toString

 

 

위와 같은 Value Object의 경우 포맷을 Java Doc과 같은 문서에 명시하는 것이 좋습니다.

또한 해당 포맷으로 객체를 생성할 수 있는 정적 팩토리 메서드 혹은 생성자를 제공하는 것이 좋습니다.


 

2. 보안 정책으로 인해 모든 필드가 다 노출되면 안 되는 경우

 

toString 메서드가 public 메서드이기 때문에 해당 메서드에서 노출되는 필드들은 사실상 공개되었다고 봐도 무방합니다.

저자는 객체가 가진 모든 정보를 보여주는 것이 좋다고 하지만 로그 정보가 탈취될 수 있다는 가정을 항상 깔고 가야 하기 때문에 고객의 개인정보와 같은 필드는 toString에 노출시키지 않는 것을 권장합니다.

그래도 디버깅할 때 어떤 객체에서 문제가 발생했는지 특정지어야하는 경우가 있으므로 개인정보를 제외한 시퀀스 아이디 정도만 toString에 노출시키는 것이 좋습니다.

 

3. 추상 클래스

 

추상 클래스의 경우 toString 메서드를 재정의하고 toString 메서드에서 표출할 정보를 반환하는 메서드를 추상 메서드로 정의하는 것을 권장합니다.

아래 예제가 앞서 설명한 내용을 완벽하게 구현합니다.


 

toString 메서드를 재정의하지 않아도 되는 케이스

아래의 클래스들은 toString 메서드를 재정의하지 않아도 됩니다.

  • 정적 유틸리티 클래스
  • Enum 클래스

 

1. 정적 유틸리티 클래스

 

정적 유틸리티 클래스의 경우 static 메서드들만 있고 별도 필드가 없으므로 toString 메서드를 제공하지 않아도 됩니다.

 

2. Enum 클래스

 

Enum 클래스는 자바가 이미 완벽한 toString 메서드를 제공하니 별도로 재정의하지 않아도 됩니다.

 

참고

이펙티브 자바
이펙티브 자바 완벽 공략 1부 - 백기선 강사님

반응형