java

자바 - enum

Feb 21, 2020

열거(enum)

목차

1. 열거
2. 열거의 메서드
3. 생성사 메서드 필드
4. 인스턴스의 구현부
5. 정적 멤버
6. switch문에 열거 사용하기


1. 열거

public enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };



2. 열거의 메서드

열거 타입은 인스턴스들이 고정이므로 equals 메서드를 사용할 필요가 없다. 간단히 == 를 사용하면된다.

toString 메서드를 구현하지 않아도 된다. 열거 객체의 이름을 주는 toString 메서드가 자동으로 주어진다.

public enum Size {
    SMALL,
    MEDIUM,
    LARGE,
    EXTRA_LARGE
}
Size mySize = Size.valueOf("SMALL");

mySize = Size.SMALL로 설정한다. valueOf 메서드는 주어진 이름에 해당하는 인스턴스가 없으면 예외를 던진다.

열거 타입의 정적 메서드 values는 모든 인스턴스를 선언한 순서로 정렬한 배열을 반환한다.

Size[] allValues = Size.values();
for(Size s : allValues) {
    System.out.println(s);
}
/*
SMALL
MEDIUM
LARGE
EXTRA_LARGE
*/

ordinal 메서드는 enum 선언에서 인스턴스의 위치(0부터)를 돌려준다. Size.MEDIUM.ordinal()은 1을 반환한다.

모든 열거 타입 E는 자동으로 Comparable<E>를 구현하므로 자체의 객체만을 대상으로 비교할 수 있다. 비교할 때는 ordinal value로 비교한다.

java.lang.Enum<E> 클래스의 메서드



3. 생성자 메서드 필드

원한다면 열거 타입에 생성자, 메서드, 필드를 추가할 수 있다.

열거의 생성자는 반드시 private이다.

public enum Size {
    SMALL("S"), MEDIUM("M"), LARGE("L"), EXTRA_LARGE("XL");

    private String abbreviation;

    Size(String abbreviation) {
        this.abbreviation = abbreviation;
    }

    public String getAbbreviation() { return abbreviation; }
}



4. 인스턴스의 구현부

enum 인스턴스에 각각 메서드를 추가할 수 있지만, 이렇게 하면 열거에 정의된 메서드를 오버라이드해야 한다. 다음은 계산기의 예다.

public enum Operation {
    ADD("+") {
        public int eval(int arg1, int arg2) { return arg1 + arg2; }
    },
    SUBTRACT("-") {
        public int eval(int arg1, int arg2) { return arg1 - arg2; }
    },
    MULTIPLY("*") {
        public int eval(int arg1, int arg2) { return arg1 * arg2; }
    },
    DIVIDE("/") {
        public int eval(int arg1, int arg2) { return arg1 / arg2; }
    };

    private String symbol;
    Operation(String symbol) { this.symbol = symbol; }
    public String getSymbol() { return symbol; }
    
    public abstract int eval(int arg1, int arg2);
}
public class Calculater {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("First operand: ");
        int a = in.nextInt();
        System.out.print("Operator: ");
        String opSymbol = in.next();
        System.out.print("Second operand: ");
        int b = in.nextInt();
        for (Operation op : Operation.values()) {
            if (op.getSymbol().equals(opSymbol)) {
                int result = op.eval(a, b);
                System.out.println(result);
            }
        }
    }
}
/*
First operand: 1
Operator: *
Second operand: 3
3
*/



5. 정적 멤버

enum은 정적 멤버를 가질 수 있다. 생성 순서에 주의해야 한다. 열거 상수가 생성된 다음에 정적 멤버가 생성된다. 그러므로 열거 생성자에서는 정적 멤버를 참조할 수 없다.

public enum Modifier {
    PUBLIC, PRIVATE, PROTECTED, STATIC, FINAL, ABSTRACT;
    private int mask;

    static {
        int maskBit = 1;
        for (Modifier m : Modifier.values()) {
            m.mask = maskBit;
            maskBit *= 2; 
        }
    }
    
    public int getMask() {
        return mask;
    }
}



6. switch문에 열거 사용하기

switch문에 열거 상수를 사용할 수 있다.

public class Calculator2 {
    

    public static int eval(Operation op, int arg1, int arg2) {
        int result = 0;
        switch (op) {
            case ADD: result = arg1 + arg2;
            case SUBTRACT: result = arg1 - arg2;
            case MULTIPLY: result = arg1 * arg2;
            case DIVIDE: result = arg1 / arg2;
        }
        return result;
    }
    
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("First operand: ");
        int a = in.nextInt();
        System.out.print("Operator: ");
        String opSymbol = in.next();
        System.out.print("Second operand: ");
        int b = in.nextInt();
        for (Operation op : Operation.values()) {
            if (op.getSymbol().equals(opSymbol)) {
                System.out.println(eval(op, a, b));
            } 
        }
    }
}