enum.values ​​()-결정적인 반환 된 열거 형의 순서입니다.


105

열거 형이 있습니다 SOME_ENUM.

public enum SOME_ENUM {
  EN_ONE,
  EN_TWO,
  EN_THREE;
}

SOME_ENUM.values()항상 열거 형 선언의 순서로 열거를 돌려 : EN_ONE, EN_TWO, EN_THREE? 규칙입니까 아니면 다음 JDK 릴리스에서 변경되지 않을 것이라는 보장이 없습니까?


1
이 열거 형을 반복하여 읽은 코드의 다른 위치보다 목록을 채우기 위해 열거 형을 반복합니다.
Skarab

11
@MitchWheat 당신이 List 보존 순서에 의존하는 것과 같은 이유로 : JDK는 당신에게 확실한 보장을 제공하고 이러한 보장에 의존하는 것은 당신이 더 간결하고 더 나은 코드를 작성하는 데 도움이되는 도구이기 때문입니다. 물론 "변경되지 않는 것이 보장 되는가?"라는 질문이 있습니다. 대답하기 불가능합니다. 당신은 확실히 그것에 의지 할 수 없습니다.
Fletch 2012-08-13

답변:


144

Java 언어 사양은 다음과 같은 명시 적 언어를 사용합니다.

@이 열거 형의 상수를 포함하는 배열을 선언 된 순서대로 반환합니다. [Source]

예, 신고 순서대로 반환됩니다. 누군가가 클래스를 변경하면 시간이 지남에 따라 순서가 변경 될 수 있으므로이를 사용하는 방법에 대해 매우주의해야합니다.


1
누군가가 나중 코드 버전에서 중간에 값을 추가하면 다른 요소의 서수 값이 변경되므로 (Enum.ordinal ()) 메서드를 참조하십시오. 이러한 이유로 직렬화 메커니즘으로 서수 위치에 의존하지 않는 것이 가장 좋습니다 (즉, db에 저장하지 않음).
Matt

1
해당 사양의 소스에 연결 하시겠습니까?
Dan Grahn 2015


16

예, 그 순서대로 반품하는 것이 보장됩니다.

그러나 ordinal()예를 들어 새 항목을 삽입 한 후 변경 될 수 있으므로 해당 값 과 값 에 의존하지 않아야합니다 .


현자 조언 +1. ordinal () 주제에서 Effective Java는 열거 형 유형에 멤버 필드를 추가 할 것을 제안합니다.
ide

9

값이 선언 된 순서에 따라 결정됩니다. 그러나 사용자 (또는 다른 사람)가 향후 값을 재정렬 / 삽입 / 제거하지 않을 것이라는 보장은 없습니다 . . 따라서 주문에 의존해서는 안됩니다.

효과적인 Java 2nd. Edition은 항목 31을 밀접하게 관련된 주제에 바칩니다 : 서수 대신 인스턴스 필드 사용 :

서수에서 열거 형과 관련된 값을 파생하지 마십시오. 대신 인스턴스 필드에 저장하십시오.


3
"누군가가 미래에 값을 재정렬하지 않을 것이라는 보장은 없습니다."-이것이 바로 제가 주문에 의존하고 싶은 이유입니다. :-)! 나중에 항목을 다시 주문하여 프로그램의 동작을 변경하고 싶습니다. Bloch는 서수에 의존하지 않는 것이 옳으며 asker의 예가 실제로 EN_TWO와 같은 열거 형을 포함하는 경우 서수에 의존하고 있으므로이를 수행해서는 안됩니다. 그러나 명령에 의존하는 것은 완벽합니다. 실제로 주문이 보장되는 것처럼 주문을위한 필드를 만드는 것은 중복 코드를 작성하는 것이므로, Effective Java와 같은 책에서는하지 말라고합니다.
Fletch 2012-08-13

@Fletch, 죄송합니다, 나는 당신을 잘 따르지 않습니다. 나에게 이것은 당신이 enum의도하지 않은 목적 으로 사용하려는 것처럼 들립니다 .
Péter Török

유명한 "Planet"열거 형이 있다고 가정 해 보겠습니다. UI에서 태양으로부터의 거리 순서대로 행성을 나열하려고합니다. 이것을 어떻게 가장 잘 달성 할 수 있습니까? enum 클래스 내에서 행성 상수를 올바른 순서로 정렬 한 다음 UI에서 열거 형을 열거합니다. 주문이 신뢰할 수 있기 때문에 이것은 작동합니다. 그게 제가 말하는 종류입니다. 언젠가 지구가 화성보다 태양에 더 가까워진다면 당연히 그런 순간에 당신의 따뜻한 마음의 첫 번째 일은 당신의 코드를 유지하는 것입니다! 그래서 당신은 행성 클래스로 가서 지구를 화성 이전으로 이동합니다.
Fletch 2012-08-16

@Fletch, 지구는 이미 화성보다 태양에 더 가깝습니다 ;-) 그러나 나는 당신이 의미하는 바를 이해합니다. 그러나이 경우 행성의 순서는 실제로 태양으로부터의 평균 거리의 함수이며, 이는 단순한 서 수가 아니므로 IMHO는 각 행성에 대해 별개의 필드로 저장하는 것이 좋습니다. 그런 다음 사소한 비교기를 통해 태양과의 평균 거리를 기준으로 행성을 비교하고이 비교기를 사용하여 순서를 지정할 수 있습니다. 이것은 IMHO는 깨끗하고 완벽한 솔루션입니다. 새로운 동료가 행성이 분명히 알파벳 순서로 나열 되어야한다고 결정하자마자 솔루션이 중단되는 반면 ;-)
Péter Török

1
Hahaha ermm 네, 어쨌든 그것은 모두 음모입니다. 화성은 없습니다. 처음에는 토성을 사용하려고했지만 어떤 행성이 근처에 있는지 기억할 수 없었지만 화성 계획은 역효과를 낸 것 같습니다. :-). 어쨌든 ...이 경우 비교자는 좋지만 더 많은 코드가 필요하다는 단점이 있습니다. 소스 코드 순서에 의존한다면 클래스 주석에 이것을 문서화하는 것이 좋을 것이라고 생각합니다. 동료가 읽을 수도 있습니다.
Fletch 2012-08-16

7

다른 답변은 좋지만 이에 대해 언급하지 마십시오.

"규칙입니까 아니면 다음 Jdk 릴리스에서 변경되지 않을 것이라는 보장이 없습니까?"

미래의 JDK에 대한 보증이 존재한다고 생각하지 않으므로 걱정하지 마십시오. 그들을 강제 할 방법이 없을 것이며, 미래의 JDK 리드는 그러한 보증을 포기하기로 결정할 수도 있습니다. 그것은 웨스트 민스터 의회 시스템과 같습니다. "어떤 의회도 미래의 의회를 묶을 수 없습니다."

즉, JDK의 역사는 뛰어난 일관성을 보여줍니다. 그들은 많은 주요 변경 사항을 만들지 않으므로 현재 지정된 (관찰 된 것이 아니라) 동작이 보존 될 것이라고 확신 할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.