본문 바로가기
Develop/Java

[Java] toString() 파헤치기

by 연로그 2022. 2. 15.
반응형

목차

1. 개요

2. toString()의 목적

3. toString()의 구조

4. 코드의 개선

5. 결론


 


1. 개요

 

자동차를 나타내는 Car 클래스를 선언했다.

Car 클래스에는 name과 position이 존재하고 아래와 같은 문자열로 나타내려고 한다.

 

ex) name = "연로그", position = 3

👉 연로그 : ---

 

따라서 아래와 같은 객체를 만들고 toString()을 오버라이드 해주었다.

public class Car {
    private final String name;
    private int position;

    public Car(String name) {
        this.name = name;
        this.position = 0;
    }

    public void go() {
        this.position++;
    }

    @Override
    public String toString() {
        return name + " : " + getGauage();
    }
    
    private String getGauage() {
        return "-".repeat(position);
    }
}

 

헌데 리뷰어님의 코멘트를 확인하니..

우테코 - 카일님

 

왜... toString은 안된다는 거지...?

 

객체의 상태에 대한 값을 포함해 반환하는 것이니 당연히 해당 객체에서 관리해야한다고 생각했다.

getter의 사용을 줄이고 싶었다.

기능을 분리하기 위해 조금 더 생각해보기로 하자.

 


2. toString()의 목적

 

Oracle docs에서 설명한 toString()은 아래와 같다.

public String toString()

Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method. The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

getClass().getName() + '@' + Integer.toHexString(hashCode())
Returns: a string representation of the object.

 

요약해서 말해보자면 toString은 간결하면서 이해하기 쉬운 형태의 정보를 반환해야 한다.

이펙티브 자바에 따르면 toString을 잘 구현한 클래스는 사용이 즐겁고 디버깅이 편리하다.

 

예를 들어 Map 객체를 출력했을 때 윗줄보다 아랫줄이 훨씬 보기 편하다.

  • {yeonLog=Phone@aae23gs}
  • {yeonLog=010-1234-5678}

 


3. toString()의 구조

 

가장 기본적인 형태의 Object의 toString() 코드를 열어보았다.

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

 

"클래스명@16진수_hashCode"를 반환한다.

(+ toHexString: 정수를 16진수 표현의 문자열로 변환)

 

예를 들어 새로운 Car라는 클래스를 생성해보자.

toString()를 오버라이드 하지 않고 사용하면 아래와 같은 결과가 나타난다.

toString() 결과

 


4. 코드의 개선

 

개요에서 오버라이드 했던 toString()은 Car에서 선언하기 적합하지 않다는 생각이 들었다.

객체 상태를 이용해 특정 문자열로 변환시키는 것은 View의 역할에 적합하다 판단하고 로직을 옮겼다.

 

하지만 나중의 유지보수나 디버깅을 위해 toString()을 선언하면 편하겠다고 생각했다.

IntelliJ에서 alt+insert를 누르면 getter, setter 등의 자동으로 메소드를 선언해주는 편리한 기능이 있다.

 

toString 항목을 누르자 아래와 같은 메소드를 자동으로 생성해주었다.

@Override
public String toString() {
    return "Car{" +
            "name='" + name + '\'' +
            ", position=" + position +
            '}';
}

 

참고로 toString()은 가능한 그 객체가 지닌 주요 정보를 모두 반환하는 것이 좋다.
지나치게 큰 데이터, 문자열 표현이 적합하지 않은 경우 등도 존재하니 모든 정보를 반환할 필요는 없다.

 

Car에서는 특별한 정보가 없어 IntelliJ에서 생성해준 toString()을 그대로 사용했지만 커스텀도 가능하다.

format을 이용할 경우에 개발자의 의도를 명확히 밝혀야 하는 것이 중요하다.

 


5. 결론

 

  • toString()간결하고 이해하기 쉽고 유익한 정보를 담기

  • ModelView 역할 구분하기
    • Model: 객체의 정보나 데이터 관리.
    • View: 사용자 인터페이스 요소. 출력.

  • getter를 제한하는 목적 착각하지 않기
    • 객체에 메시지를 보내 스스로 상태에 대한 처리 로직을 수행하기 위해 제한

참고

  1. Oracle docs - Object
  2. Effective Java / 조슈아 블로크
반응형

'Develop > Java' 카테고리의 다른 글

[Java] ConcurrentModificationException 에러  (0) 2022.02.24
[Java] Built-in Package  (0) 2022.02.17
[JPA] Table 'DB.hibernate_sequence' doesn't exist 에러  (0) 2022.01.14
[JPA] 프록시와 영속성 전이  (0) 2022.01.13
[JPA] Entity 매핑  (0) 2022.01.10