특정 객체에 관한 정보를 출력해야할 상황에서, 나에게 두명의 개발자가 각각 toString() 메소드를 쓰는 것이 어떠냐는 의견을 준 적이 있다. toString() 에 관해 공부했었을 때에는 개발자가 해당 객체의 정보를 알아보기 쉽게하기 위해 사용한다, 정도로 이해했었으나 정확히 나의 의견을 말할 수 없었기에 제대로 모른다고 판단하여 알아보았다.
toString() 은 객체의 정보
를 반환한다. toString() 메소드는 모든 객체의 상위 클래스인 Object 가 정의한 메소드이다. 가장 최상위에 있는 클래스이기 때문에 모든 클래스는 기본적으로 toString() 을 사용할 수 있다. 일부 이미 오버라이딩 되어있는 클래스들도 있지만 오버라이딩 되어 있지 않을 경우에는 클래스 이름@16진수코드
을 반환한다.
public String toString() {
getClass().getName() + '@' + Integer.toHexString(hashCode());
}
실제로 객체를 생성하여 그 값을 출력해보면 다음과 같은 결과가 출력된다.
public class Main {
public static void main(String[] args) {
Car car = new Car("car", 0);
System.out.println(car.toString());
}
}
public class Car {
private final String name;
private int position;
public Car(String name, int position) {
this.name = name;
this.position = position;
}
}
car.toString() 을 생략하여 car 만을 출력해도 동일한 결과가 나온다.
toString() 을 재정의하면 새로 정의한 형식으로 값이 출력된다.
public class Main {
public static void main(String[] args) {
Car car = new Car("car", 0);
System.out.println(car);
}
}
public class Car {
private final String name;
private int position;
public Car(String name, int position) {
this.name = name;
this.position = position;
}
@Override
public String toString() {
return name + " : " + position;
}
}
그러나 다른 언어처럼 일반 문자열을 출력하면 문자열에 저장되어 있는 값이 그대로 나온다. 그것은 String 객체가 toString() 메소드를 이미 오버라이딩 했기 때문에 저장된 값이 출력되는 것이다.
System.out.println("string");
이펙티브 자바에서 말하는 toString() 을 재정의할 때의 이점은 다음과 같다.
디버깅
할 때 출력되는 값이 toString() 이므로 객체의 상태를 바로 알 수 있어 개발 시 편리하다.로그
를 남길 때 알아보기 쉬운 값을 저장하기에 편리하다.그렇기 때문에 모든 상황에서 객체가 가지는 대부분의 중요 정보를 반환하도록 요구한다.
그렇다면 객체의 정보를 사용자에게 보여줄 때 toString() 메소드를 오버라이딩해서 사용해도 될까? 하는 생각이 들었다. 어차피 toString() 도 객체의 정보를 반환하고, 사용자에게 객체의 정보를 보여줄 때 원하는 포맷으로 가공하여 toString() 을 활용해도 될까 궁금했다.
이펙티브 자바에 의하면, toString() 은 객체의 정보를 알릴때 사용
하는 것이며 개발의 편의성을 위해 모든 상황에서 toString() 을 오버라이딩 할 것을 권한다.
그러나 toString() 특정한 포맷을 지정해둘 경우 그 외의 정보가 필요하다면 그에 따른 getter 또는 별도의 메소드가 필요하고, 재정의한 toString() 을 활용한다면 값을 파싱해서 사용해야 하기 때문에 성능이 나빠지고 불필요한 작업이 든다는 이유로 반대한다.
toString() 은 디버깅을 할 때처럼 개발 시에 사용하는 것을 권장하고 사용자에게 보여주기 위한 값은 별도의 메소드를 생성하는 것이 적절하고 생각한다.
20210304 추가
우아한테크코스 로또 미션 1단계 피드백
질문 및 리뷰어님의 답변
Q. 실무에서도 모든 경우에 toString 을 오버라이딩하여 사용하는가?
A. 로깅하는 객체에 한해 로그로 남기고 싶은 값만 IDE 의 자동생성 기능을 이용하여 오버라이딩한다.
나의 답변
=> 로그를 남기는 등 특별한 상황에서만 사용하는 경우도 있다.