2023-java-study / book-study

북 스터디 기록 레포지토리
0 stars 0 forks source link

[item 38] 특정 연산 #118

Open NuhGnod opened 1 year ago

NuhGnod commented 1 year ago

p.235 반면, 특정 연산에서는 EnumSet, EnumMap을 사용하지 못한다.

책에서 작성한 test메소드는 타입 매개변수를 <T extends Enum<T> & Operation> 로 선언했습니다. EnumMap은

public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
    implements java.io.Serializable, Cloneable

EnumSet은

public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
    implements Cloneable, java.io.Serializable

로 그냥 클래스이고, 열거타입도 아니고, Operation을 구현하지도 않았기 때문에 사용하지 못한다라고 생각했습니다.

그런데, 이렇다면 모든 연산에서 쓸수 없는것 아닌가? 라는 생각이 드는데 책에서 특정 연산에서라고 특정한 이유가 궁금합니다.

혹시 이 부분에 대해 다른 분들은 어떻게 이해하셨나요?

gmelon commented 1 year ago

정확한 질문에 대한 답은 아닌 갓 같지만 제가 이 부분을 읽을 때 이해했던 내용을 적어보면, 책에서 말한 첫번째 방법에선 T 가 Enum<T> 를 extends 한 것으로 제핰하고 있으므로 컴파일러가 이를 인지할 수 있게되어 enum만을 키로 받는 enummap, enumset 사용에 문제가 없지만

두번째 방법은 단순히 Operation을 원소로 갖는 컬렉션을 받는 것이므로 컴파일러 입장에선 해당 원소가 enum이다 라는 것까지는 알 방법이 없으므로 형변환 등을 사용하지 않으면 EnumSet, EnumMap 을 바로 사용하기엔 문제가 있을 수도 있겠다. 라고 저는 이해했었습니다.

ssstopeun commented 1 year ago

https://github.com/Java-Bom/ReadingRecord/issues/96

gmelon commented 1 year ago

인터페이스 Operation이 아래와 같고,

static interface Operation {
    void method();
}

이를 구현하는 DefaultOperation, Default2Operation이 아래와 같을 때

static enum DefaultOperation implements Operation {

    PLUS {
        public void method() {}
    },
    MINUS {
        public void method() {}
    }

}

static enum Default2Operation implements Operation {

    PLUS {
        public void method() {}
    },
    MINUS {
        public void method() {}
    }

}

EnumMap은 하나의 타입만 받을 수 있으므로 아래 메서드 하단 두 줄 중 한 줄은 무조건 실패하게 됩니다.

void someMethod(List<? extends Operation> list) {
    EnumMap<DefaultOperation, Object> map = new EnumMap<>(DefaultOperation.class);

    map.put((DefaultOperation) list.get(0), ""); // 가능
    map.put((Default2Operation) list.get(1), ""); // 불가능
}

반면, 책에서 소개한 첫 번째 방법의 경우

image

opEnumType을 받아 하나의 enum 타입만 받는게 정해져있으므로 이러한 문제가 생기지 않을 것 같네요.