본문 바로가기
Language/Effective java

열거 타입과 애너테이션

by y.j 2022. 7. 18.
728x90

확장할 수 있는 열거타입이 필요하며 인터페이스를 사용하라

타입 안전 열거 패턴과 열거 타입은 차이점이 있다. 열거 타입을 확장하게 된다면 고려할 요소가 늘어나 설계와 구현이 더 복잡해진다.

  타입 안전 열거 패턴 열거 타입
확장 가능 O X
값 추가 O X

하지만, 확장 할 수 있는 열거 타입은 연산코드에서 어울린다. Operation 인터페이스에 apply 메서드를 정의해놓고 BasicOperation에서 구현하도록 강제한다.

public enum BasicOperation implements Operation {
    PLUS("+") {
        public double apply(double x, double y) { return x + y; }
    },
    MINUS("-") {
        public double apply(double x, double y) { return x - y; }
    },
    TIMES("*") {
        public double apply(double x, double y) { return x * y; }
    },
    DIVIDE("/") {
      public double apply(double x, double y) { return x / y; }
    };

    private final String symbol;

    BasicOperation(String symbol) {
        this.symbol = symbol;
    }

    @Override
    public String toString() {
        return symbol;
    }
}

 

enum자체는 확장 할 수 없지만 Operation을 통해서 확장시킬 수 있다.

public enum ExtendedOperation implements Operation {
    EXP("^") {
        @Override
        public double apply(double x, double y) {
            return Math.pow(x,y);
        }
    },
    REMAINDER("%") {
        @Override
        public double apply(double x, double y) {
            return x%y;
        }
    };
    private final String symbol;
    ExtendedOperation(String symbol) {
        this.symbol = symbol;
    }


    @Override
    public String toString() {
        return symbol;
    }
}

 

확장 열거 타입 테스트

<T extends Enum<T> & Operation>은 매개변수 Class<T>가 Enum이면서 동시에 Operation의 하위타입이여야 한다는 것을 명시한다. 

public class Main {
    public static void main(String[] args) {
        double x = 2;
        double y = 4;
        test(ExtendedOperation.class, x, y);
    }
    private static <T extends Enum<T> & Operation> void test(
            Class<T> opEnumType, double x, double y) {
        for(Operation op : opEnumType.getEnumConstants())
            System.out.printf("%f %s %f = %f%n" ,
                    x, op, y, op.apply(x,y));
    }
}

 

아래 코드처럼 한정적 와일드 카드를 사용할 수 있겠지만 EnumMap이나 EnumSet을 쓰지 못할수도 있다.

public class Main {
    public static void main(String[] args) {
        double x = 2;
        double y = 4;
        test(Arrays.asList(ExtendedOperation.values()), x, y);
    }
    private static  void test(Collection<? extends Operation> opSet, double x, double y) {
        for(Operation op : opSet)
            System.out.printf("%f %s %f = %f%n" ,
                    x, op, y, op.apply(x,y));
    }
}
728x90

'Language > Effective java' 카테고리의 다른 글

열거 타입과 애너테이션  (0) 2022.07.23
열거 타입과 애너테이션  (0) 2022.07.20
열거 타입과 애너테이션  (0) 2022.07.13
제네릭  (0) 2022.06.26
제네릭  (0) 2022.06.19

댓글