학습한 내용을 정리한 포스팅입니다. 틀린 내용이 있다면 지적해주시면 감사하겠습니다.🙇🏻♀️
상수를 선언하기 위한 것으로 여러 상수를 정의할 때 사용하면 유용하다.
값뿐만 아니라 타입도 체크하기 때문에 안전하다고 볼 수 있다(타입에 안전한 열거형 - typesafe enum)
아래와 같이 정의하면 된다.
enum 이름 {상수이름1, 상수이름2, 상수이름3, ...}
public enum PizzaStatus {
ORDERED,
READY,
DELIVERED;
}
위처럼 PizzaStatus를 정의했다. 사용할 때는 ‘이름.상수명’으로 사용할 수 있다. (PizzaStatus.ORDERED 등)
아래의 예시는 baeldung에 나와있는 예시를 보고 이해한 대로 다시 써보았습니다. 틀린 내용이 있다면 지적해주시면 감사하겠습니다
public class Pizza {
private PizzaStatus status;
public enum PizzaStatus {
ORDERED,
READY,
DELIVERED;
}
public boolean isDeliverable(){
if (getStatus() == PizzaStatus.READY) {
return true;
}
return false;
}
//아래에 getter와 setter가 있다고 하자.
}
위의 예시처럼 enum을 활용하는 메서드를 정의할 수도 있다. 여기에서 눈여겨 봐야하는 점은 isDeliverable 메소드에서 열거형 상수간 비교는 equals()
가 아닌 ==
로 비교 한다는 것이다. enum 타입은 JVM안에서 상수의 인스턴스로 존재하기 때문에 ==
오퍼레이터를 사용한다. 사실 ==
오퍼레이터는 컴파일 타임, 런타임 안전성을 제공한다.
if(testPizza.getStatus().equals(Pizza.PizzaStatus.DELIVERED));
if(testPizza.getStatus() == Pizza.PizzaStatus.DELIVERED);
==
를 사용했을 경우 비교하는 두 값 모두 null일 수 있고 그렇게 된다면 NullPointerException이 발생하지 않는다. 이와 다르게 equals
메소드를 사용하면 NullPointerException이 발생할 것이다. 그렇기 때문에 ==
오퍼레이터를 사용했을 때 런타임 안전성을 보장한다고 할 수 있다. 컴파일 시에도 만약 위와 같은 두 가지 경우가 있다고 한다면…
equals 메소드로 비교할 경우 enum의 값과 getStatus 메소드의 값이 우연히 같을 수 있다(true). 하지만 논리적으로는 false여야 한다. ‘==’ 오퍼레이터를 사용하면 이런 상황을 피할 수 있기 때문에 컴파일 타임 안전성이 보장된다.
아래와 같은 경우에는 비교할 수 없기 때문에 에러가 발생할 것이다. (비교할 대상인 TestColor라는 enum을 갖고 있지 않기 때문에)
if(testPizza.getStatus().equals(TestColor.RED));
if(testPizza.getStatus() == TestColor.RED);
values(): Enum 클래스가 가지고 있는 상수를 배열에 담아 리턴한다. 모든 열거형이 가지고 있는 것으로 컴파일러가 자동으로 추가 해준다.
static T valueOf(Class enumType,String name): 지정된 열거형에서 이름이 일치하는 열거형 상수를 리턴한다.
Class Declaration
public abstract class Enum<E extends Enum> extends Object
implements Comparable, Serializable
위에서 볼 수 있다시피 Enum은 추상 클래스로 우리는 Enum 클래스의 객체를 생성할 수 없다.
Enum 클래스는 10개의 유용한 메소드를 제공한다. 대부분은 오브젝트 클래스에서 오버라이딩 된 것이고 final로 선언되어 있어 프로그래머가 수정 할 수 없다. 아래는 해당 메소드들이다.
Enum 타입을 사용하기 위한 특화된 Set이다.
Enum 상수를 특정한 Set으로 표현하는 것은 내부의 비트 벡터 표현이 사용되기 때문에 효율적이라고 할 수 있다 == 산술 비트 연산을 사용하기 때문에 메모리를 적게 쓰고 연산이 빠르다. (이 부분은 내가 잘 이해한건지… 그리고 그게 왜..? 인지 아직 잘 모르겠어서 앞으로도 계속 찾아봐야 할 것 같다)
EnumSet은 RegularEnumSet과 JumboEnumSet, 2개의 구현체를 가지고 있는 추상 클래스인데 enum의 상수의 숫자에 따라 둘 중 알맞는 것이 선택된다. long으로 표현 가능한 경우는 RegularEnumSet이 사용되고 그렇지 않으면 JumboEnumSet이 사용된다.