그것은 사용하기 OK인가 ==
자바 열거 형에, 또는 내가 사용해야합니까 .equals()
? 내 테스트에서는 ==
항상 작동하지만 그것이 보장되는지 확실하지 않습니다. 특히, 어떤이없는 .clone()
나는 그것을하는 열거 얻을 수 있는지 알고하지 않도록, 열거의 방법 .equals()
과는 다른 값을 반환을 ==
.
예를 들어, 이것이 괜찮습니까?
public int round(RoundingMode roundingMode) {
if(roundingMode == RoundingMode.HALF_UP) {
//do something
} else if (roundingMode == RoundingMode.HALF_EVEN) {
//do something
}
//etc
}
또는 다음과 같이 작성해야합니까?
public int round(RoundingMode roundingMode) {
if(roundingMode.equals(RoundingMode.HALF_UP)) {
//do something
} else if (roundingMode.equals(RoundingMode.HALF_EVEN)) {
//do something
}
//etc
}
답변
2 센트 만 : 다음은 Sun에서 게시 한 Enum.java의 코드와 JDK의 일부입니다.
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
// [...]
/**
* Returns true if the specified object is equal to this
* enum constant.
*
* @param other the object to be compared for equality with this object.
* @return true if the specified object is equal to this
* enum constant.
*/
public final boolean equals(Object other) {
return this==other;
}
}
답변
예, == 괜찮습니다-각 값에 대한 단일 참조가 보장됩니다.
그러나 라운드 메서드를 작성하는 더 좋은 방법이 있습니다.
public int round(RoundingMode roundingMode) {
switch (roundingMode) {
case HALF_UP:
//do something
break;
case HALF_EVEN:
//do something
break;
// etc
}
}
더 나은 그것을하는 방법은 열거 자체 내에서 기능을 넣어, 그래서 당신은 단지 호출 할 수 있습니다 roundingMode.round(someValue)
. 이것은 Java 열거 형의 핵심입니다 . 다른 곳에서 발견되는 “명명 된 값”과는 달리 객체 지향 열거 형입니다.
편집 : 사양은 명확하지 않지만 섹션 8.9 는 다음과 같이 말합니다.
열거 형 유형의 본문에는 열거 형 상수가 포함될 수 있습니다. 열거 형 상수는 열거 형 유형의 인스턴스를 정의합니다. 열거 형에는 열거 형 상수에 의해 정의 된 것 외에 다른 인스턴스가 없습니다.
답변
예, 마치 열거 형의 각 값에 대해 싱글 톤 인스턴스를 만든 것과 같습니다.
public abstract class RoundingMode { public static final RoundingMode HALF_UP = new RoundingMode (); public static final RoundingMode HALF_EVEN = new RoundingMode (); private RoundingMode () { // 전용 범위는이 클래스 외부의 모든 하위 유형을 방지합니다. } }
그러나 의 enum
구조는 당신에게 다양한 혜택을 제공합니다 :
- 각 인스턴스의 toString ()은 코드에 지정된 이름을 인쇄합니다.
- (다른 게시물에서 언급했듯이) enum 유형의 변수는
switch-case
제어 구조를 사용하여 상수와 비교할 수 있습니다 . - 열거 형의 모든 값은
values
각 열거 형 유형에 대해 ‘생성 된’필드를 사용하여 쿼리 할 수 있습니다. - 다음은 큰 wrt ID 비교입니다. 열거 형 값은 복제없이 직렬화를 유지합니다.
연재는 큰 고치 야. 열거 형 대신 위의 코드를 사용하는 경우 ID 평등이 작동하는 방식은 다음과 같습니다.
RoundingMode 원본 = RoundingMode.HALF_UP; assert (RoundingMode.HALF_UP == 원본); // 통과 ByteArrayOutputStream baos = 새로운 ByteArrayOutputStream (); ObjectOutputStream oos = 새로운 ObjectOutputStream (baos); oos.writeObject (원본); oos.flush (); ByteArrayInputStream bais = new ByteArrayInputStream (baos.toByteArray ()); ObjectInputStream ois = new ObjectInputStream (bais); RoundingMode deserialized = (RoundingMode) ois.readObject (); assert (RoundingMode.HALF_UP == 역 직렬화 됨); // 실패 assert (RoundingMode.HALF_EVEN == 역 직렬화 됨); // 실패
당신은 할 수 관련된 기술을 사용하여, 열거하지 않고이 문제를 해결 writeReplace
하고 readResolve
, (참조 http://java.sun.com/j2se/1.4.2/docs/api/java/io/Serializable.html를 ) …
요점은-Java가 동등성을 테스트하기 위해 열거 형 값의 ID를 사용할 수 있도록하는 것입니다. 권장되는 연습입니다.
답변
== 두 개체의 참조를 비교합니다. 열거 형의 경우 인스턴스가 하나만 있으므로 동일한 열거 형 두 개에 대해 ==가 true가됩니다.
참고:
http://www.ajaxonomy.com/2007/java/making-the-most-of-java-50-enum-tricks
(Sun 문서에서 아무것도 찾을 수 없음)
답변
흥미로운 코드가 있습니다. :디
public enum YesNo {YES, NO}
public static void main(String... args) throws Exception {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
YesNo yesNo = (YesNo) unsafe.allocateInstance(YesNo.class);
Field name = Enum.class.getDeclaredField("name");
name.setAccessible(true);
name.set(yesNo, "YES");
Field ordinal = Enum.class.getDeclaredField("ordinal");
ordinal.setAccessible(true);
ordinal.set(yesNo, 0);
System.out.println("yesNo " + yesNo);
System.out.println("YesNo.YES.name().equals(yesNo.name()) "+YesNo.YES.name().equals(yesNo.name()));
System.out.println("YesNo.YES.ordinal() == yesNo.ordinal() "+(YesNo.YES.ordinal() == yesNo.ordinal()));
System.out.println("YesNo.YES.equals(yesNo) "+YesNo.YES.equals(yesNo));
System.out.println("YesNo.YES == yesNo " + (YesNo.YES == yesNo));
}
답변
열거 형은 다형성 코드를 방해하는 좋은 장소입니다.
enum Rounding {
ROUND_UP {
public int round(double n) { ...; }
},
ROUND_DOWN {
public int round(double n) { ...; }
};
public abstract int round(double n);
}
int foo(Rounding roundMethod) {
return roundMethod.round(someCalculation());
}
int bar() {
return foo(Rounding.ROUND_UP);
}
답변
RMI / IIOP를 통해 enum을 전송할 때 문제가 있습니다. 이 스레드를 참조하십시오 :
http://www.velocityreviews.com/forums/t390342-enum-equality.html
