자바 기본 복습 11. Enum
11주차 과제 Enum
📌 목표
자바의 열거형에 대해 학습하세요.
📌 학습할 것
- enum 정의하는 방법
- enum이 제공하는 메소드 (values()와 valueOf())
- java.lang.Enum
- EnumSet
📜 시작에 앞서
- 백기선 님의 라이브 스터디(2020년 11월부터 2021년 3월까지) 커리큘럼을 따라 진행한 학습입니다
- 뒤늦게 알게 되어 스터디 참여는 못했지만 남아있는 스터디 깃허브 주소와 유튜브 영상을 참고했습니다
📑 enum 정의하는 방법
enum 이란?
- 열거형: 관련된 여러 상수를 정의하고, 그 외 값을 허용하지 않는다 -> 관련된 상수 집합 구성을 컴파일타임에 다 알고 있을 때 사용
- 자바 열거형은 완전한 형태의 클래스기 때문에 생성자, 메서드, 필드 추가 가능
자바에서 열거형 지원하기 전에는?
- 정수 열거 패턴 사용
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER; = 2;
public static final int SEASON_FALL = 3;
public static final int SEASON_WINTER = 4;
public static final int BACKEND_FRAMEWORK_SPRING = 1;
public static final int BACKEND_FRAMEWORK_DJANGO = 2;
public static final int BACKEND_FRAMEWORK_EXPRESS = 3;
public static final int BACKEND_FRAMEWORK_LARAVE = 4;
- 모두
int
이므로 타입 안전성 X (위의 경우 두SPRING
이 모두 int 1이기 때문에==
비교시true
반환) - 위와 같이
SPRING
의 의미가 여럿일 경우 변수명에 직접 이름 구분 필요 - 열겨형
enum
은 이러한 문제점을 해결하고, 여러 장점을 가져오는데...
열거형 정의
enum 열거형명 { 상수명1, 상수명2 ...}
enum BackendFramework { SPRING, DJANGO, EXPRESS, LARAVE }
enum Season { SPRING, SUMMER, FALL, WINTER;
Season(){ // private 생성자만 가능
System.out.println(this + " init");
}
}
public class Enum {
public static void main(String[] args) {
System.out.println("=====before=====");
System.out.println(Season.SPRING);
System.out.println("=====after=====");
System.out.println();
Season season1 = Season.SPRING;
Season season2 = Season.SPRING;
System.out.println("season1 == season2 :" + season1 == season2);
System.out.println();
BackendFramework bf1 = BackendFramework.SPRING;
// System.out.println(season1 == bf1); 컴파일 에러! 타입 안전
}
}
/*
실행결과
=====before=====
SPRING init
SUMMER init
FALL init
WINTER init
SPRING
=====after=====
season1 == season2 :true
*/
- 자바 열거형은 상수 하나당 자신의 인스턴스를
public static final
로 하나씩 생성 - 자바 열거형은 생성자는
private
만 가능- 따라서 열거형은 밖에서 접근할 수 없다
- 각 열거형에 대해 타입 안전성
열거 타입 상수 각각을 틍정 데이터와 연결하고 싶다면?
- 열거 타입 상수 각각을 특정 데이터와 연결지으려면 생성자에서 데이터를 받아 인스턴스 필드에 저장
// <이펙티브 자바 3/E> 코드 34-3 데이터와 메서드를 갖는 열거 타입
public enum Planet {
MERCURY(3.302e+23, 2.439e6),
VENUS (4.869e+24, 6.052e6),
EARTH (5.975e+24, 6.378e6),
MARS (6.419e+23, 3.393e6),
JUPITER(1.899e+27, 7.149e7),
SATURN (5.685e+26, 6.027e7),
URANUS (8.683e+25, 2.556e7),
NEPTUNE(1.024e+26, 2.477e7);
private final double mass; // 질량(단위: 킬로그램)
private final double radius; // 반지름(단위: 미터)
private final double surfaceGravity; // 표면중력(단위: m / s^2)
// 중력상수(단위: m^3 / kg s^2)
private static final double G = 6.67300E-11;
// 생성자
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
surfaceGravity = G * mass / (radius * radius);
}
public double mass() { return mass; }
public double radius() { return radius; }
public double surfaceGravity() { return surfaceGravity; }
public double surfaceWeight(double mass) {
return mass * surfaceGravity; // F = ma
}
}
출저: 이펙티브 자바 3/E
상수별 메서드 구현
- 하나의 메서드가 상수별로 다르게 동작해야 할때 ->
switch
문 대신 상수별 메서드 구현 고려
enum Enum {
VAL1 {@Override public void info() { ... }},
VAL2 {@Override public void info() { ... }},
VAL3 {@Override public void info() { ... }},
VAL4 {@Override public void info() { ... }};
public abstract void info(...));
}
이외 고려사항 예시
- 열거 타입 상수 일부가 같은 동작을 공유할 때 -> 전략 열거 타입 패턴 고려
- 필요할 때 사용후 예시 추가 하기
- 기존 열거 타입에 상수별 동작을 혼합할 때 ->
switch
문 고려- 필요할 때 사용후 예시 추가 하기
Enum 활용 예시
📑 java.lang.Enum
java.lang.Enum
은 추상 클래스로, 열거형이 자동으로 상속받는 부모 클래스Enum
은impelements
는 가능하나extends
는 불가
- 인터페이스
Comparable<E>, Serializable
구현
java.lang.Enum
메서드
Method | Description |
---|---|
clone() | CloneNotSupportedException 예외 던짐 |
compareTo(E o) | 비교 가능한 타입일시 각 ordinal의 차이를 반환 |
getDeclaringClass() | 열거형의 Class 객체 반환 |
name() | 열거형 상수의 이름을 문자열로 반환 |
ordinal() | 열거형 상수의 순서 반환(0부터 시작) |
valueOf(Class<T> enumType, String name) | 지정된 열거형(param1)에서 이름(param2)과 일치하는 열거형 상수 반환 |
- 열거형 상수의 순서가 필요하다고
ordinal()
을 사용하지 말자, 순서에따라 자동으로 부여하기때문에 유지보수 어렵다- 열거 타입 상수에 연결된 값이 필요하다면 인스턴스 필드에 저장
- 메서드 전체는 java8 docs: Enum 참고
- 외에도 열거형에 컴파일러가 추가하는 두 메서드는 다음 파트에서
📑 enum이 제공하는 메소드 values()와 valueOf()
values()
와valueOf(String name)
은 컴파일러가 모든 열거형에 자동으로 추가
Method | Description |
---|---|
values() | 열거형의 모든 상수를 배열에 담아 반환 |
valuesOf(String name) | 열거형 상수의 이름으로 문자열 상수에 대한 참조 반환 Planet.valueOf("EARTH") == Planet.EARTH |
📑 EnumSet
EnumSet
을 사용하면 열거형 상수의 값으로 구성된 집합을 간단히 생성할 수 있다Set
인터페이스를 구현한 클래스며 이에 대한 다형성 활용 가능- 생성자를 클라이언트가 호출할 수 없다, 대신
EnumSet.of()
등 메서드 사용- 이러한 메서드 방식에 대한 자세한 내용은 정적 팩토리 메서드 참고
생성 예시
import java.util.EnumSet;
enum Planet {
MERCURY,
VENUS,
EARTH,
MARS,
JUPITER,
SATURN,
URANUS,
NEPTUNE;
}
public class EnumSetEx {
public static void main(String[] args) {
EnumSet<Planet> planets = EnumSet.allOf(Planet.class);
EnumSet<Planet> planetsHasRing = EnumSet.of(Planet.JUPITER, Planet.SATURN, Planet.URANUS, Planet.NEPTUNE);
System.out.println("planets : " + planets);
System.out.println("planetsHasRing : " + planetsHasRing);
}
}
📑📌📜✏️
Author And Source
이 문제에 관하여(자바 기본 복습 11. Enum), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@butterf12/자바-기본-복습-11.-Enum저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)