Programing

열거 형 이름이 Java로 인턴됩니까?

lottogame 2021. 1. 8. 07:44
반응형

열거 형 이름이 Java로 인턴됩니까?


열거 형 이름이 Java로 인턴됩니까?

enum1.name() == enum2.name(), 동일한 이름의 경우 보장 됩니까? 그리고 enum.name()인턴이 보장되는 문자열 과 비교 하는 것이 안전합니다 .


이에 대한 명시적인 보장은 없지만 최종 결과는 enum동일한 이름을 가진 상수에 대해 항상 비교가 성공하도록 바운드됩니다 .

enum A {enum1};
enum B {enum1};
System.out.println(A.enum1.name() == B.enum1.name()); // Prints "true"

그 이유는 Java 컴파일러가 의 유일한 보호 생성자를 Enum호출 Enum하여 enum의 이름을 전달 하는 방식으로의 서브 클래스를 구성 하기 때문입니다 .

protected Enum(String name, int ordinal);

이름은 문자열 리터럴 형식으로 생성 된 코드에 포함됩니다. String문서 에 따르면

모든 리터럴 문자열 및 문자열 값 상수 식은 인턴됩니다.

이것은 enum상수의 이름 이 동일 할 때 표현식이 성공한다는 암시 적 보증에 해당합니다 . 그러나 나는이 행동에 의존하지 equals(...)않고 대신 사용 합니다. 왜냐하면 내 코드를 읽는 사람은 내가 실수했다고 생각하고 그의 머리를 긁을 것이기 때문입니다.


아니.

Dasblinkenlight의 답변 은 지금까지 우리가 가진 최고의 답변입니다. 거기에서 그는 말한다 :

그 이유는 Java 컴파일러가 단일 보호 생성자를 Enum호출 Enum's하여 enum의 이름을 전달 하는 방식으로의 서브 클래스를 구성 하기 때문입니다.

그들은 문자열 상수이기 때문에 거기에서 인턴을받습니다.

그러나 JLS, 8.9.2, Enum Body Declarations 에는 다음이 있습니다.

실제로 컴파일러는 Enum형식 의 기본 생성자에서 Stringint매개 변수를 선언 하여 형식 을 미러링 할 수 enum있습니다. 그러나 이러한 매개 변수는 다른 컴파일러가 기본 생성자의 형식에 동의 할 필요가 없기 때문에 "암시 적으로 선언 된"것으로 지정 되지 않습니다 . enum유형 의 컴파일러 만이 enum상수 를 인스턴스화하는 방법을 알고 있습니다 . 다른 컴파일러는 해당 필드가 초기화 된 방식에 관계없이 형식 ( §8.9.3 ) 의 암시 적으로 선언 된 public static필드에 의존 할 수 있습니다 .enum

(강조 광산)

그래서 우리는 생성자를 호출 할 것입니다. 그러나 우리는 어떤 특별한 방식으로도 그렇게하도록 강요받지 않고 컴파일러에서 우리 자신의 생성자를 관리 할 수 ​​있습니다.

따라서 이름을 리터럴로 저장하지 않음으로써 어떻게 든 이름을 인턴하지 않는 올 바르고 JLS 호환 Java 컴파일러를 작성할 수 있습니다. 예, 악의적으로 코드를 손상시키기 위해 의도적으로 수행하지만 사양에 따라 올바른 동작입니다.


예, 실제로 말했습니다.

모든 정상적인 구현은 문자열을 인턴합니다. 나는 이런 종류의 행동 가정 하는 것이 안전하다고 말하고 싶습니다 . 하지만 보장 할 수는 없으므로 실제 코드에서 이것을 본다면 주석에 철저히 설명되어 있어도 매우 만족스럽지 않을 것입니다.

지정되지 않고 구현에 특정한 동작에 의존하지 마십시오. 정말로 필요하다면 단위 테스트를 작성하십시오. 그리고 assert코드와 많은 설명을 넣으십시오 . 접근 방식이 실제로 어떤 일을 할 것인지 측정하십시오.

enum회원의 이름과 회원 intern()을 사용하기 전에 수동으로 반복 해보십시오 . 그렇게하면 당신이하는 일이 즉시 명확해질 것입니다. 이것은 안정적으로 작동하지 않습니다. 주석을 참조하십시오.


문자열을 사용하면 Strings의 equals 메소드를 사용하고 싶을 것입니다. 그 외에도 등호 연산자와 비교할 수있는 열거 형이 이미 있습니다. 이것은 어떤 시나리오에서 발생합니까?

즉, 예, .equals 메서드는 동일한 경우 true를 반환합니다.

나는 등식 연산자에 대해 잘 모르겠고, 그것을 찾아 보지 않고는 그것을 사용하는 것이 좋지 않은 프로그래밍이라고 말할 수 있습니다.


Enum에 대한 Oracle 문서는 다음과 같이 말합니다.

열거 형은 변수가 미리 정의 된 상수 집합이되도록하는 특수 데이터 유형입니다. 변수는 사전 정의 된 값 중 하나와 같아야 합니다. 일반적인 예로는 나침반 방향 (NORTH, SOUTH, EAST 및 WEST 값)과 요일이 있습니다.

이것이 사실이라면 예, enum1.name() == enum2.name()이름이 같으면 사실이 보장됩니다.

또한 name()javadoc 메소드에서 :

public final String name () enum 선언에 선언 된대로 정확하게이 enum 상수의 이름을 리턴합니다. 대부분의 프로그래머는 toString 메서드가 사용자에게 더 친숙한 이름을 반환 할 수 있으므로이 메서드보다 우선적으로 toString () 메서드를 사용해야합니다. 이 방법은 주로 정확한 이름을 얻는 데 의존하는 특수한 상황에서 사용하도록 설계되었으며 이는 릴리스 마다 다르지 않습니다 . 반환 값 :이 열거 형 상수의 이름

예를 들어 두 개의 열거 형이 Days있고 MyDaysSUNDAY가 공통 값이고 열거 형 개체 값 사이에 ==가있는 경우 SUNDAY는 두 문자열을 비교할 때 true를 반환합니다. http://ideone.com/ 의 작업 예제를 참조하십시오. U1Bmcw .

/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
    public static enum Day{SUNDAY, MONDAY, TUESDAY};
    public static enum MyDays{SUNDAY};

    public static void main (String[] args) throws java.lang.Exception
    {
        MyDays m = Ideone.MyDays.SUNDAY;
        Day d = Ideone.Day.SUNDAY;

        System.out.println(d.name() == m.name());
    }
}

ReferenceURL : https://stackoverflow.com/questions/27908213/are-enum-names-interned-in-java

반응형