Java 열거 멤버 비교: == 또는 equals()?
Java Enum은 프라이빗 컨스트럭터와 다수의 퍼블릭 스태틱멤버가 있는 클래스로 컴파일 되어 있는 것을 알고 있습니다.열거형의 두할 때 '우리'를 사용했어요.equals()
public useEnums(SomeEnum a)
{
if(a.equals(SomeEnum.SOME_ENUM_VALUE))
{
...
}
...
}
마침 연산자 '이퀄'을 가 몇 개 되었습니다.==
.syslog()
public useEnums2(SomeEnum a)
{
if(a == SomeEnum.SOME_ENUM_VALUE)
{
...
}
...
}
어떤 교환기를 사용해야 하나요?
둘 다 기술적으로 옳다.「」의를 알 수 ..equals()
,로 됩니다.==
.
용 i i i i를 쓴다.==
safe에 null safe.displed는 null safe.displed.
수 있다==
사용되다enum
에는 ": enum" 을 사용할 수 .==
인스턴스를 비교합니다.다음은 언어 사양에 따라 제공되는 보증입니다(제가 강조합니다).
JLS 8.9의 개요
열거형에는 열거형 상수에 의해 정의된 인스턴스 이외의 인스턴스가 없습니다.
열거형을 명시적으로 인스턴스화하려고 하면 컴파일 시 오류가 발생합니다.
final clone
in the method in the method in 。Enum
할 수 있습니다.enum
상수는 클로닝할 수 없습니다.시리얼라이제이션메커니즘에 의한 특별한 처리를 통해 역직렬화 결과 중복 인스턴스가 생성되지 않습니다.열거형식의 반영 인스턴스화는 금지되어 있습니다.하면, 「4」의 인스턴스가 발생하지 않게 됩니다.」의 가 발생하지 않게 .enum
은 의 정의 .enum
상수를 지정합니다.각 1개의 이기 때문입니다.
enum
상수, 두 객체 참조를 비교할 때 방법 대신 연산자를 사용하는 것은 허용된다. 만약 적어도 그들 중 하나가 상수를 참조한다는 것이 알려진 경우.equals
in the method in the method in 。Enum
는 입니다.final
호출하는super.equals
는 인수에 따라 결과를 반환하고 ID 비교를 수행합니다).
추천할 . 만약 당신이 싱글톤 패턴을 고집한다면, 그것을 구현하는 가장 좋은 방법은 싱글 엘리먼트를 사용하는 것입니다.enum
(「유효 Java 2nd Edition, Item 3: 프라이빗 컨스트럭터 또는 열거형을 사용하여 싱글톤 속성 적용」을 참조해 주세요.또, 싱글톤에서의 스레드 안전성).
==
★★★★★★★★★★★★★★★★★」equals
'하다'라고 할 .==
에 대한 실행 가능한 대안이 아니다equals
이 : ', ', ', ' 등),enum
는 두 즉, 두 가지 차이점이 있습니다.
==
던지지 않다NullPointerException
enum Color { BLACK, WHITE };
Color nothing = null;
if (nothing == Color.BLACK); // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException
==
시 .
enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };
if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
if (Color.BLACK == Chiral.LEFT); // DOESN'T COMPILE!!! Incompatible types!
★★★★★★★★★★ 。==
용용 가능 능??
Bloch는 특히 인스턴스를 적절하게 제어하는 불변의 클래스는 클라이언트에 다음을 보증할 수 있다고 언급합니다.==
사용할 수 있습니다. enum
예를 들어 구체적으로 언급하고 있습니다.
항목 1: 컨스트럭터 대신 정적 공장 방식을 고려하십시오.
[...] 이를 통해 불변의 클래스는 두 개의 동일한 인스턴스가 존재하지 않음을 보증할 수 있습니다.
a.equals(b)
만약이라면a==b
클래스가 이 보증을 하면 클라이언트는 이 보증을 사용할 수 있습니다.==
operator 대신equals(Object)
퍼포먼스가 향상될 수 있습니다.Enum 타입은 이 보증을 제공합니다.
요약하자면, 다음과 같은 인수는==
에enum
다음과 같습니다.
- 그건 효과가 있다.
- 더 빨라요.
- 런타임에 더 안전해.
- 컴파일할 때 더 안전해
사용.==
각 열거 상수에 대해 하나의 개체만 존재하기 때문에 두 개의 열거 값을 비교하는 것이 효과적입니다.
덧붙여서, 실제로 사용할 필요가 없습니다.==
null-safe code를 작성해야 합니다.equals()
다음과 같습니다.
public useEnums(final SomeEnum a) {
if (SomeEnum.SOME_ENUM_VALUE.equals(a)) {
…
}
…
}
이는 왼쪽에서 상수 비교로 알려진 모범 사례로 반드시 따라야 합니다.
남들이 말했듯이 둘 다==
그리고..equals()
대부분의 경우 효과가 있습니다.다른 사람들이 지적한 완전히 다른 유형의 오브젝트를 비교하지 않는 컴파일 시간의 확실성은 유효하고 유익하지만, 2개의 다른 컴파일 시간 유형의 오브젝트를 비교하는 특정 종류의 버그는 FindBugs(그리고 아마도 Eclipse/IntelliJ 컴파일 시간 검사)에서도 발견될 수 있습니다.안전성이 크게 향상되지 않는다는 것을 알게 되었습니다.
단,
- 이 사실은
==
NPE를 떠올리지 않는 것이 단점입니다.==
...의 필요성은 거의 없습니다.enum
될 타입null
를 통해 표현할 수 있는 추가 상태이기 때문에null
에 추가할 수 있습니다.enum
추가 예로서뜻밖의 경우null
, NPE 를 사용하고 싶다.==
거짓으로 묵묵히 평가하다그러므로 나는 런타임에 그것이 더 안전하다는 의견에 동의하지 않는다; 절대 하지 않는 습관을 들이는 것이 좋다.enum
가치가 있다@Nullable
. - 라는 주장
==
더 빠르다는 것은 가짜이기도 하다.대부분의 경우,.equals()
컴파일 시간 유형이 열거 클래스인 변수, 그리고 그러한 경우 컴파일러는 이것이 다음과 같은 것을 알 수 있습니다.==
(왜냐하면enum
의equals()
메서드는 덮어쓸 수 없습니다.) 및 함수 호출을 최적화할 수 있습니다.컴파일러가 현재 이 작업을 수행할지는 모르겠지만 그렇지 않은 경우 Java 전체의 성능 문제로 판명되면 100,000명의 Java 프로그래머가 특정 컴파일러 버전의 성능 특성에 맞게 프로그래밍 스타일을 변경하는 것보다 컴파일러를 수정하는 것이 낫습니다. enums
오브젝트입니다.기타 모든 개체 유형에 대한 표준 비교는 다음과 같습니다..equals()
,것은 아니다.==
예외로 하는 것은 위험하다고 생각합니다.enums
왜냐하면 실수로 오브젝트를 비교하게 될 수 있기 때문입니다.==
대신equals()
특히, 만약 당신이 리팩터링의enum
non-enum 클래스로 이동합니다.리팩터링의 경우 위에서부터의 It works 포인트가 잘못되어 있습니다.자기 자신을 설득하기 위해==
정답입니다. 문제의 값이 다음 중 하나인지 여부를 확인해야 합니다.enum
혹은 원시인일 수도 있고, 만약 그것이 비-인 경우enum
틀리겠지만 코드를 아직 컴파일하기 때문에 놓치기 쉽습니다.를 사용하는 유일한 경우.equals()
이 경우 코드가 컴파일되지 않기 때문에 놓치기 어렵습니다.이런 이유로,.equals()
올바른 것으로 식별하기가 훨씬 쉬우며 향후 리팩터링으로부터도 안전합니다.
실제로 Java 언어에서는 왼쪽 값의 .filength()를 호출하고 개체 ID를 위한 별도의 연산자를 도입하기 위해 == on Objects를 정의해야 한다고 생각합니다만, Java는 그렇게 정의되지 않았습니다.
요약하자면, 나는 여전히 그 주장들이 다음을 사용하는 것에 찬성한다고 생각한다..equals()
위해서enum
종류들.
사용하는 것을 선호합니다.==
대신equals
:
또, 이미 여기서 설명한 다른 이유 외에, 자신도 모르는 사이에 버그가 발생할 가능성이 있습니다.이 enum이 완전히 동일하지만 분리된 팩에 포함되어 있다고 가정합니다(흔하지는 않지만 발생할 수 있습니다).
첫 번째 열거:
package first.pckg
public enum Category {
JAZZ,
ROCK,
POP,
POP_ROCK
}
두 번째 열거:
package second.pckg
public enum Category {
JAZZ,
ROCK,
POP,
POP_ROCK
}
그럼 다음에서와 같은 값을 사용한다고 가정해 봅시다.item.category
어느 것이first.pckg.Category
두 번째 열거형을 Import합니다(second.pckg.Category
대신, 자신도 모르는 사이에 첫 번째가 됩니다.
import second.pckg.Category;
...
Category.JAZZ.equals(item.getCategory())
그래서 너는 항상 얻을 수 있을 것이다.false
due는 true로 예상되지만 다른 열거형입니다.item.getCategory()
이JAZZ
보기 어려울 수도 있어요.
그 대신 연산자를 사용하면==
컴파일 오류가 발생합니다.
연산자 ==을(를) "second.pckg"에 적용할 수 없습니다.카테고리", "first.pckg"카테고리"
import second.pckg.Category;
...
Category.JAZZ == item.getCategory()
dr;dr
또 다른 옵션은 유틸리티 방법입니다.
Objects.equals( thisEnum , thatEnum )
Objects.equals
안전상의 이유로
.timeout()이 아닌 연산자 ==와 동일합니다.
어떤 교환기를 사용해야 하나요?
세 번째 옵션은 Java 7 이후에 추가된 유틸리티 클래스에 있는 정적 메서드입니다.
예
다음은 열거형을 사용한 예입니다.
boolean areEqual = Objects.equals( Month.FEBRUARY , Month.JUNE ) ; // Returns `false`.
혜택들
이 방법에는 몇 가지 이점이 있습니다.
- 특수한 안전성
- 둘 다 특수한 순서입니다.
true
- null 중 하나1개
false
- 투척 위험 없음
- 둘 다 특수한 순서입니다.
- 콤팩트, 가독성
구조
가 사용하는 논리는 무엇입니까?
OpenJDK의 Java 10 소스 코드를 참조하십시오.
return
( a == b )
||
(
a != null
&&
a.equals( b )
)
;
이 둘을 비교하기 위한 대략적인 타이밍 테스트를 다음에 나타냅니다.
import java.util.Date;
public class EnumCompareSpeedTest {
static enum TestEnum {ONE, TWO, THREE }
public static void main(String [] args) {
Date before = new Date();
int c = 0;
for(int y=0;y<5;++y) {
for(int x=0;x<Integer.MAX_VALUE;++x) {
if(TestEnum.ONE.equals(TestEnum.TWO)) {++c;}
if(TestEnum.ONE == TestEnum.TWO){++c;}
}
}
System.out.println(new Date().getTime() - before.getTime());
}
}
IF를 하나씩 코멘트합니다.분해된 바이트 코드의 위의 두 가지 비교를 다음에 나타냅니다.
21 getstatic EnumCompareSpeedTest$TestEnum.ONE : EnumCompareSpeedTest.TestEnum [19]
24 getstatic EnumCompareSpeedTest$TestEnum.TWO : EnumCompareSpeedTest.TestEnum [25]
27 invokevirtual EnumCompareSpeedTest$TestEnum.equals(java.lang.Object) : boolean [28]
30 ifeq 36
36 getstatic EnumCompareSpeedTest$TestEnum.ONE : EnumCompareSpeedTest.TestEnum [19]
39 getstatic EnumCompareSpeedTest$TestEnum.TWO : EnumCompareSpeedTest.TestEnum [25]
42 if_acmpne 48
첫 번째(등호)는 가상 콜을 실행하여 스택으로부터의 리턴 부울을 테스트합니다.두 번째(==)는 스택에서 직접 개체 주소를 비교합니다.첫 번째 경우에는 더 많은 활동이 있습니다.
두 IF를 한 번에 하나씩 사용하여 이 테스트를 여러 번 실행했습니다."=="가 훨씬 더 빠릅니다.
음파탐지기 규칙 중 하나는Enum values should be compared with "=="
이유는 다음과 같습니다.
열거값의 동일성을 테스트하는 중
equals()
enum은 오브젝트이고 모든 자바 개발자가 알고 있기 때문에 완전히 유효합니다.==
오브젝트의 내용을 비교하는 데 사용하면 안 됩니다.동시에,==
enums:
예상되는 비교(내용)는 다음과 같습니다.
equals()
null safele safe
equals()
는 런타임 체크가 아닌 컴파일 타임(정적) 체크를 제공합니다.
이러한 이유로,
==
보다 바람직하다equals()
.
마지막으로 중요한 것은==
enums는 거의 틀림없이 보다 읽기 쉽다(덜 상세하다).equals()
.
enum의 경우 둘 다 옳고 옳다!!
이 이외의 것을 사용하는 경우==
열거형 상수를 비교하는 것은 말도 안 된다.마치 물건을 비교하고 있는 것과 같습니다.하지 마세요!
단, Sun JDK 6u10 이전 버전에는 이력상의 이유로 흥미로운 버그(BugId 627778)가 있었습니다.이 버그로 인해, 의 올바른 사용이 방해되었습니다.==
비록 이것은 다소 궁지에 몰린 경우이긴 하지만, 탈직렬화된 열거형에서.
enums는 에 의해 선언된 각 열거 상수에 대해 1개의 인스턴스(싱글톤 등)를 반환하는 클래스입니다.public static final field
(불변의) 그래서==
연산자는 그 동등성을 확인하는 데 사용될 수 있습니다.equals()
방법
==에서 enum을 쉽게 사용할 수 있는 이유는 정의된 각 인스턴스가 싱글톤이기 때문입니다.따라서 ==를 사용한 ID 비교는 항상 가능합니다.
그러나 ==는 enums와 함께 작동하기 때문에 사용한다는 것은 모든 코드가 해당 열거형의 사용과 긴밀하게 연결되어 있다는 것을 의미합니다.
예를 들어 Enums는 인터페이스를 구현할 수 있습니다.현재 Interface1을 구현하는 열거형을 사용하고 있다고 가정합니다.나중에 같은 인터페이스의 구현으로 변경 또는 새로운 클래스 Incless1이 도입됩니다.그런 다음, Impact1 인스턴스를 사용하기 시작하면 이전에 ==를 사용했기 때문에 많은 코드를 변경하고 테스트할 수 있습니다.
따라서 정당한 이익이 없는 한 좋은 관행으로 간주되는 것을 따르는 것이 가장 좋습니다.
다른 모든 훌륭한 답변에 덧붙일 것이 하나 있습니다.당신이 간단한 람다를 사용할 때, 저는 정말 선호합니다.equals
에 걸쳐서==
메서드 참조를 사용할 수 있기 때문입니다.
다음 람다를 고려해 보십시오.
Stream.of(SomeEnum.A, SomeEnum.B).anyMatch(e -> e == SomeEnum.B);
Stream.of(SomeEnum.A, SomeEnum.B).anyMatch(e -> e.equals(SomeEnum.B));
후자는 다음과 같이 변환할 수 있습니다.
Stream.of(SomeEnum.A, SomeEnum.B).anyMatch(SomeEnum.B::equals));
나는 다원성 자궁 경화제의 답변을 보완하고 싶다.
나는 개인적으로 동등한 것을 선호한다.하지만 형식 호환성 검사를 하지 않습니다.그게 중요한 한계라고 생각합니다.
컴파일 시 유형 호환성 검사를 수행하려면 열거형에서 사용자 지정 함수를 선언하고 사용합니다.
public boolean isEquals(enumVariable) // compare constant from left
public static boolean areEqual(enumVariable, enumVariable2) // compare two variable
이것에 의해, NPE 보호, 코드 읽기, 컴파일시에 타입의 호환성 체크 등, 양쪽의 솔루션의 메리트를 모두 얻을 수 있습니다.
또한 enum에는 정의되지 않은 값을 추가하는 것이 좋습니다.
한마디로 둘 다 장단점이 있다.
다른 한편으로, 그것은 사용하기에 장점이 있다.==
(다른 답변에서 설명한 바와 같이)
한편, 어떠한 이유로 enum을 다른 어프로치(통상 클래스인스턴스)로 치환하는 경우는,==
당신을 물어요. (BTDT)
언급URL : https://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals
'programing' 카테고리의 다른 글
C에 심플한 HTTP 서버를 구축하다 (0) | 2022.08.14 |
---|---|
기본 인증을 사용하는 Vue 리소스 (0) | 2022.08.13 |
Vuejs의 매초 악리콜이 느리다 (0) | 2022.08.13 |
동일한 인수를 가진 동일한 메서드에 대한 여러 콜에서 Mockito 사용 (0) | 2022.08.13 |
Java에서 밀리초를 "X분, x초"로 변환하는 방법 (0) | 2022.08.13 |