열거형
열거형은 서로 연관된 상수의 집합을 의미한다.
상수는 변하지 않는 값으로, final 키워드로 선언 할 수 있다.
열거형은 상수들을 간편하게 관리할 때 유용하게 사용될 수 있고, 변하지 않는 데이터를 다룰 때 사용된다.
열거형을 사용하지 않고 상수를 설정하게 되면
코드예시
public static final int SPRING = 1;
public static final int SUMMER = 2;
public static final int FALL = 3;
public static final int WINTER = 4;
public static final int DJANGO = 1;
public static final int SPRING = 2; // 계절의 SPRING과 중복 발생!
public static final int NEST = 3;
public static final int EXPRESS = 4;
위의 코드처럼 final 키워드로 int형 데이터를 상수로 지정 한 것을 볼 수 있다.
여기서 문제점이 있는데, 변수명에 따라 중복될 수 있어 컴파일 에러가 발생할 수 있다.
물론, 이 경우 인터페이스를 사용해서 상수를 구별해서 사용하면 어느정도 해결된다.
interface Seasons {
int SPRING = 1, SUMMER = 2, FALL = 3, WINTER = 4;
}
interface Frameworks {
int DJANGO = 1, SPRING = 2, NEST = 3, EXPRESS = 4;
}
하지만 이 경우 또또 문제가 생긴다.
인터페이스로 별도로 만들어놓은 변수이기 때문에 타입 안정성이 떨어진다는 것이다.
if (Seasons.SPRING == Frameworks.SPRING) {...생략...}
계절의 SPRING(봄) , 프레임워크의 SPRING은 서로 의미가 다른데도 비교가 가능해지는 것이다. (인터페이스에서 그냥 따로 선언한 것 뿐이지 사실 둘다 int형 자료이기 때문에)
쉽게 말하면 이 사진과 비슷하다.

이 문제를 해결하려면, 저 위의 변수들을 서로 다른 클래스에 저장해서 상수로 선언하면 된다.
그런데, 이러면 코드도 길어지고, switch문을 못쓴다.
class Seasons {
public static final Seasons SPRING = new Seasons();
public static final Seasons SUMMER = new Seasons();
public static final Seasons FALL = new Seasons();
public static final Seasons WINTER = new Seasons();
}
class Frameworks {
public static final Frameworks DJANGO = new Frameworks();
public static final Frameworks SPRING = new Frameworks();
public static final Frameworks NEST = new Frameworks();
public static final Frameworks EXPRESS = new Frameworks();
}
변수 8개를 주제에 맞게만 저장하면 되는데, 인터페이스로는 타입 안정성이 떨어지고, 클래스로 하면 코드 개판나고 스위치문 못쓴다.
(클래스로 선언하면 스위치문 못쓰는 이유: 스위치문은 정해진 타입만 넣어서 돌릴 수 있는데, 클래스로 선언하면 사용자 정의타입이기 때문이다. (사전에 자바 안에 정해져 있지 않다.)
아주 뭐 답답한 상황이다.
이를 해결하기 위해 열거형 enum이 있다!
작성예시
enum Seasons { SPRING, SUMMER, FALL, WINTER }
enum Frameworks { DJANGO, SPRING, NEST, EXPRESS }
간단히 다른 변수명을 선언하는것 처럼 enum (변수명) {내용} 으로 처리하면 된다.
이렇게 하면 타입안정성이 확보되고, 코드도 짧아져서 가독성도 높고, 스위치문도 사용 가능하다!
enum을 switch 문에 적용 한 예시
enum chicken{
fried,
sauce,
onion
}
public class EnumTest {
public static void main(String[] args) {
chicken menu = chicken.sauce; // 열거형 상수에 접근 ( 열거형이름.상수명)
// menu에 chicken.sauce을 담음
chicken[] allchicken = chicken.values(); //열거형 자료에 정의된 상수들을 배열로 반환
for(chicken x : allchicken){
System.out.printf("%s = %d%n",x.name(), x.ordinal());
//name, ordinal 메서드 사용, 이름과 순서 반환
}
chicken findchicken = chicken.valueOf("onion");
// valueOf 메서드로 열거형에서 이름과 일치하는 열거형 상수 반환 상수가 의도한 상수랑 같은지 확인
System.out.println(findchicken);
System.out.println(chicken.onion == chicken.valueOf("onion"));
switch (menu){
case fried:
System.out.println("fried");
break;
case sauce:
System.out.println("sauce");
break;
case onion:
System.out.println("onion");
break;
}
}
}
//출력
fried = 0
sauce = 1
onion = 2
onion
true
sauce
여기서 참고해야 하는것은 열거형은 선얼 될 때 내부에 선언되는 상수에 0부터 정수값을 할당한다.
enum Seasons {
SPRING, //정수값 0 할당
SUMMER, //정수값 1 할당
FALL, //정수값 2 할당
WINTER //정수값 3 할당
}
또한 열거형에서 적용되는 메서드들이 있다.
String | name() | 열거 객체가 가지고 있는 문자열을 리턴하며, 리턴되는 문자열은 열거타입을 정의할 때 사용한 상수 이름과 동일합니다. |
int | ordinal() | 열거 객체의 순번(0부터 시작)을 리턴합니다. |
int | compareTo(비교값) | 주어진 매개값과 비교해서 순번 차이를 리턴합니다. |
열거 타입 |
valueOf(String name) | 주어진 문자열의 열거 객체를 리턴합니다. |
열거 배열 |
values() | 모든 열거 객체들을 배열로 리턴합니다. |
'백엔드 > JAVA_이론공부' 카테고리의 다른 글
JAVA_애너테이션 (0) | 2022.09.28 |
---|---|
JAVA_제네릭 (0) | 2022.09.28 |
JAVA_인터페이스 (0) | 2022.09.22 |
JAVA_ final 키워드 (0) | 2022.09.22 |
JAVA_추상화 , 추상 클래스, abstract 제어자 (0) | 2022.09.22 |