본문 바로가기
DevelopmentTools/Java

[Java] Enum 비교는 == 일까 equals() 일까?

by 수짱수짱 2025. 10. 22.

개요

enum 객체에 관한 로직을 작성하던 도중 문득 궁금증이 생겼다...

enum은 객체다. 하지만 싱글톤 객체라는 특징이 있다.

그렇다면 enum의 비교는 == 으로 할까? 아니면 객체이기 때문에 반드시 equals()로 비교를 해야할까?

이 궁금증을 해결하기 위해 정리했던 내용을 해당 글에서 작성하고자 한다.

 

* Enum이란?

java의 enum은 클래스 인스턴스가 JVM 내에 반드시 하나만 존재하도록 보장하는 “싱글톤” 객체

 

* 간단하게 enum의 특징 정리

1. enum 생성자는 enum이 처음 참조될 때 jvm이 모든 enum 상수를 한번에 모두 생성하기 위해 선언 순서대로 생성자를 호출함

2. enum은 싱글톤 객체이기 때문에 최초의 생성자 호출 이후 객체 생성은 없다.

3. 컴파일러에서 자동으로 enum 클래스의 생성자를 private으로 막아둠. 임의로 private이 아닌 접근제한자를 붙일 시 컴파일 에러 발생

4. enum은 2번에서 말했듯 싱글톤 객체이기 때문에 spring에서 bean 등록을 하지 않아도 싱글톤 객체로 동작함

5. enum의 상수는 public static final 필드로 취급되어 클래스가 최초로 참조될 때 모든 인스턴스가 생성되는 것이다. static 필드는 클래스 초기화 시점에 만들어져야하기 때문

 

* 간단하게 enum 활용방법

enum은 행위를 나타낼 수 있다. 따라서, enum 타입에 따른 불필요한 분기문을 enum에 행위를 넣어 제거할 수 있다.

특히 추후에 타입이 추가될 수 있는데 분기문으로 작성되어 있다면 유지보수성이 굉장히 떨어지기 때문에 이러한 부분을 enum을 통해 효율성을 증가시킬 수 있다.

함수형 인터페이스 or 추상 메소드를 활용한다면 활용도가 더 좋아진다.

 

Enum의 equals() 메소드 내부

Enum.java

Enum의 equals 메소드 내부 로직을 확인해보면 equals() 메소드를 사용해도 결국 내부에선 == 를 사용하여 값을 비교하는 것을 확인할 수 있다.

특히, Enum의 equals는 final 메소드로 선언되어 있다. final 메소드는 오버라이딩이 불가능 하다는 특징을 가진다.

이말은 즉, enum의 equals()는 반드시 == 로 객체를 비교하도록 고정한다는 의미이다.

 

https://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals
https://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals

 

우리가 객체 비교시 == 을 사용하지 않고 equals()를 사용하는 이유 중 하나는 NPE를 피하기 위함도 있다.

하지만 위에서 설명한 enum의 특징 중 하나로 '싱글톤 객체'가 있다.

따라서 두 enum 객체 참조 값을 비교할 때 열거형 상수(enum)을 비교하는 경우 이들이 null일 경우는 없기에 == 연산을 사용해도 NPE는 발생하지 않는다는 것이다.

위 이미지는 스택 오버플로우에서 enum 값 비교에 == 을 사용해도 된다는 문서 내용이다.

 

 

== 과 equals() 비교

1. NPE

enum Color { BLACK, WHITE };

Color nothing = null;
if (nothing == Color.BLACK) {...}    // == is null safe
if (nothing.equals(Color.BLACK)) {...} // equals is non safe (throws NullPointerException)
  • Color가 처음으로 참조되었기 때문에 JVM에선 모든 열거형 상수 인스턴스를 생성했다 (1. BLACK, 2. WHITE)
  • ==NPE에 safe하다
  • 하지만, equals()NPE에 safe하지 못한 것을 확인할 수 있다.

 

2. Compile type miss match

enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };

if (Color.BLACK == Chiral.LEFT);      // DOESN'T COMPILE!!! Incompatible types
if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
  • ==type miss match을 컴파일에서 캐치가 가능하다 => 컴파일 에러 발생하여 타입 미스 매치를 알려줌
  • 하지만, equals()컴파일 단계에서 type miss match를 캐치할 수 없다 => 실행 시 런타임 에러 발생

 

== equals()
주소 값만 비교하기 때문에 Null safe하다
(Enum 상수는 고유한 인스턴스를 가지기 때문에 항상 참조값은 같다)
Runtime에 NPE가 발생할 수 있다
(but, Enum 객체(상수)를 먼저 두고 equals 호출 시 NPE를 피할 수 있다)
그러니 항상 equals 사용 시 뭐든 null 값이 올 수 있는 값을 먼저 두는 것은 지양하도록 하자... 
컴파일 단계에서 type missmatch 캐치 가능 컴파일 단계에서 type missmatch를 캐치 불가능

 

 

정리

== 가 더 안정적이나 equals 메소드 또한 내부에서 == 로 비교하기에 큰 차이점은 없다.

다만, 팀으로 작업하는 경우 팀 컨벤션에 따르도록 하자. 만약 이러한 컨벤션이 없다면 이번 기회에 정해보도록 하자.

 

 

Reference

 

[Java] Enum 사용 시 비교는 == 일까 equals 일까

최근에 회사 동료가 코드 검사를 하겠다며 내가 작성한 코드를 보고 리뷰를 했다. 그러던 중 공통 상수로 선언한 클래스와 Enum 클래스를 사용한 것에 대해 이야기를 하였는데, Enum 을 사용하는데

dev-jwblog.tistory.com

 

 

 

 

Comparing Java enum members: == or equals()?

I know that Java enums are compiled to classes with private constructors and a bunch of public static members. When comparing two members of a given enum, I've always used .equals(), e.g. public

stackoverflow.com

해당 stackoverflow에 정말 다양한 의견이 있다 (enum은 객체이니 equals로 비교해야 한단 의견도 있음. 필독!!)

 

 

 

[Java] Enum 은 == 비교 아니면 equals() ?

그 동안 써야지,, 하면서 계속 임시 저장되고만 있었던 게시글을 마무리 해보려고 한다. 최근 회사 내부에서 CI/CD 파이프라인에 소나큐브를 도입하면서 코드 리뷰 또한 많이 활성화가 되었다. 그

johnmarc.tistory.com

 

 

 

 

Chapter 8. Classes

class Point { int x, y, useCount; Point(int x, int y) { this.x = x; this.y = y; } static final Point origin = new Point(0, 0); } class Test { public static void main(String[] args) { Point p = new Point(1,1); Point q = new Point(2,2); p.x = 3; p.y = 3; p.u

docs.oracle.com