[java] Java Enum-이름 대신 toString을 사용하는 이유

방법을 열거 형 API를 보면 다음과 같이 name()말합니다.

열거 형 선언에서 선언 한대로이 열거 형 상수의 이름을 반환합니다. toString 메소드는보다 사용자에게 친숙한 이름을 리턴 할 수 있으므로 대부분의 프로그래머는이 메소드에 우선하여 toString 메소드를 사용해야합니다. 이 방법은 주로 정확한 이름을 얻는 데 정확성이 결정되는 특수한 상황에서 사용하도록 설계되었으며, 이는 릴리스마다 다릅니다.

왜 더 나은 toString()가요? name ()이 이미 최종일 때 toString이 재정의 될 수 있음을 의미합니다. 따라서 toString을 사용하고 누군가가 하드 코딩 된 값을 반환하도록 재정의하면 전체 응용 프로그램이 다운되었습니다 … 소스를 보면 toString () 메서드가 정확히 이름 만 반환합니다. 그건 같은거야.



답변

실제로 반환 값으로 수행하려는 작업에 따라 다릅니다.

  • 열거 형 상수를 선언하는 데 사용 된 정확한 이름을 가져와야하는 경우 재정의 된 name()대로 사용해야합니다.toString
  • 열거 형 상수를 사용자에게 친숙한 방식으로 인쇄하려면 toString재정의되었거나 사용하지 않은 것을 사용해야합니다 .

혼란 스러울 수 있다고 생각되면보다 구체적인 getXXX방법을 제공합니다 .

public enum Fields {
    LAST_NAME("Last Name"), FIRST_NAME("First Name");

    private final String fieldDescription;

    private Fields(String value) {
        fieldDescription = value;
    }

    public String getFieldDescription() {
        return fieldDescription;
    }
}


답변

사용 name()당신이 비교를하거나 코드에서 일부 내부 사용을 위해 하드 코딩 된 값을 사용하고자 할 때.

toString()사용자에게 정보를 제시 할 때 사용 합니다 (로그를보고있는 개발자 포함). toString()특정 값 을 제공하는 데 코드에 의존하지 마십시오 . 특정 문자열에 대해 테스트하지 마십시오. 누군가가 toString()수익을 올바르게 변경할 때 코드가 깨지면 이미 손상된 것입니다.

javadoc에서 (강조 광산) :

객체의 문자열 표현을 반환합니다. 일반적으로 toString 메서드는 이 객체 를 “텍스트로”나타내는 문자열을 반환 합니다. 결과는 간결하지만 유익한 표현 으로 사람 이 쉽게 읽을 수 있어야 합니다 . 모든 서브 클래스가이 메소드를 대체하는 것이 좋습니다.


답변

name()의 “내장”방법입니다 enum. 최종적이며 구현을 변경할 수 없습니다. 예를 들어 대문자 등 공백없이 열거 된 enum 상수의 이름을 반환합니다.

MOBILE_PHONE_NUMBER와 비교하십시오 Mobile phone number. 더 읽기 쉬운 버전은 무엇입니까? 나는 두 번째를 믿습니다. 이것이 차이점입니다. name()항상 반환MOBILE_PHONE_NUMBER , toString()return으로 재정의 될 수 있습니다 Mobile phone number.


답변

대부분의 사람들은 맹목적으로 javadoc의 조언을 따르지만 실제로 toString ()을 피하고 싶은 매우 구체적인 상황이 있습니다. 예를 들어 Java 코드에서 열거 형을 사용하고 있지만 데이터베이스에 직렬화 한 다음 다시 되돌려 야합니다. toString ()을 사용하면 다른 사람들이 지적했듯이 기술적으로 재정의 된 동작을 받게됩니다.

또한 데이터베이스에서 직렬화를 해제 할 수도 있습니다. 예를 들어, 항상 Java에서 작동해야합니다.

MyEnum taco = MyEnum.valueOf(MyEnum.TACO.name());

이것이 보장되지는 않지만 :

MyEnum taco = MyEnum.valueOf(MyEnum.TACO.toString());

그건 그렇고, Javadoc이 “대부분의 프로그래머가해야한다고”명시 적으로 말하는 것이 매우 이상하다는 것을 알았습니다. 사람들이 i18n과 더 호환되는 것을 사용해야하기 때문에 사람들이 “친숙한 이름”으로 사용하는 경우 열거 형의 toString에서 거의 유스 케이스를 찾지 못합니다. name () 메소드를 사용하십시오.


답변

name ()과 toString ()이 다른 의미가있는 실제 예는 단일 값 열거 형을 사용하여 싱글 톤을 정의하는 패턴입니다. 처음에는 놀랍게 보이지만 많은 의미가 있습니다.

enum SingletonComponent {
    INSTANCE(/*..configuration...*/);

    /* ...behavior... */

    @Override
    String toString() {
      return "SingletonComponent"; // better than default "INSTANCE"
    }
}

그러한 경우 :

SingletonComponent myComponent = SingletonComponent.INSTANCE;
assertThat(myComponent.name()).isEqualTo("INSTANCE"); // blah
assertThat(myComponent.toString()).isEqualTo("SingletonComponent"); // better


답변

name ()은 문자 그대로 열거 형의 Java 코드에서 텍스트 이름입니다. 즉, 실제로는 Java 코드에 나타날 수있는 문자열로 제한되지만 원하는 모든 문자열을 코드로 표현할 수있는 것은 아닙니다. 예를 들어 숫자로 시작하는 문자열이 필요할 수 있습니다. name ()은 해당 문자열을 얻을 수 없습니다.


답변

아래 코드와 같은 것을 사용할 수도 있습니다. 롬복을 사용하여 게터와 생성자를위한 상용구 코드를 작성하지 않았습니다.

@AllArgsConstructor
@Getter
public enum RetroDeviceStatus {
    DELIVERED(0,"Delivered"),
    ACCEPTED(1, "Accepted"),
    REJECTED(2, "Rejected"),
    REPAIRED(3, "Repaired");

    private final Integer value;
    private final String stringValue;

    @Override
    public String toString() {
        return this.stringValue;
    }
}