아이템 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라 요약하면 다음과 같다. 인터페이스를 이용해 열거 타입을 확장하는 효과를 가져올 수 있음. (대부분 필요없음) 효과를 보려면, 인터페이스 타입을 매개변수로 가지는 곳이 많아야 함. 이렇게 확장하는 경우 열거 타입의 한계로 인해 공통된 메서드가 반복될 수 있음. 이는 인터페이스의 default 메서드나 유틸 클래스로 분리할 수 있음. 대부분의 상황에서 열거 타입을 확장하는 건 좋지 않은 상황이다. 다음 세 가지 이유가 존재하기 때문이다. 확장한 타입의 원소는 기반 타입의 원소로 취급하지만, 그 반대는 성립하지 않기 때문이다. 기반 타입 / 확장된 타입들의 원소 모두를 순회할 방법도 마땅하지 않음. 이렇게 확장성을 높이려면 설계와 구현이..
아이템 37. ordinal() 인덱싱 대신 EnumMap을 사용하라. 배열의 인덱스를 얻기 위해 Enum의 ordinal()을 사용하는 것은 좋지 않음. EnumMap을 사용해라. 다차원인 경우 EnuMap으로 풀어내라. ordinal 인덱싱을 사용하는 것은 일반적으로 좋지 않다. 2번의 경우 배열에서 인덱싱을 사용할 때, ordinal()의 인덱싱이 배열의 크기를 넘지 않다는 것마저 사용자가 보장해야한다. 이런 이유들 때문에 사용하는 것은 좋지 않다. ordinal()에서 제공하는 인덱싱의 의미는 한 눈에 알 수 없다. 인덱싱이 제공하는 정보가 정확한 것임을 사용자가 정의해야한다. 첫번째 예시 - 안 좋은 예시 (ordinal()로 인덱싱함) 아래 코드처럼 정의된 PlantBad 클래스가 있고, en..
들어가기 전 이 글은 이펙티브 자바 책을 공부하며 작성한 글입니다. 아이템 36. 비트 필드 대신 EnumSet을 사용하라. 비트 필드를 열거 타입으로 사용하면 다음 문제가 있음. 비트 필드 값이 그대로 출력되면 해석이 어려움. 비트 필드 하나가 출력 되었을 때, 어떤 원소가 포함되었는지 알기 어려움. (3 = 0011임, 그러면 12는?) EnumSet을 사용하라. EnumSet은 내부적으로 비트 벡터로 구현되어 있음. EnumSet을 생성하면, enum의 ordinal() 메서드를 이용해서 구해지는 값을 비트 값으로 표현한 형태로 저장됨. EnumSet은 Set의 인터페이스 기능을 제공함. 내부적으로는 비트 연산을 하기 때문에 빠름. Enum을 이용하기 때문에 표현력도 좋음. 비트 필드 열거 패턴 비..
Effective Java 아이템 34. int 상수 대신 (enum)을 사용하라 열거 타입은 정수 상수 열거 패턴의 단점을 모두 극복한다. 타입 안정성 보장. 디버깅 시, 표현력 향상. 같은 열거 그룹 내의 순회하는 방법 제공. 하나의 메서드가 상수별로 다르게 동작해야 할 때, Swtich 문 대신 추상 메서드를 선언해서 각 열거형 인스턴스마다 다르게 동작하도록 할 수 있음. 상수별로 다르게 동작해야 할 때 Switch, 추상 메서드로 너무 복잡해지면 전략 패턴을 이용해 볼 수 있음. 열거 타입은 컴파일 시점에 어떤 원소가 있을지 명확하다면 사용하면 좋음. 널리 쓰이는 열거 타입은 Top Level 클래스로 만들고, 특정 톱레벨 클래스에서만 쓰인다면 멤버 클래스로 만든다. 정수 열거 패턴 기법 publ..
아이템 35. enum에서 ordinal() 대신 인스턴스 필드를 사용하라 enum은 내부에서 사용할 수 있도록 ordinal() 메서드가 제공된다. ordinal() 메서드는 enum 내부에 선언된 열거형 상수의 위치를 알려주는 메서드다. 그렇지만 가급적이면 ordinal()을 사용하는 것을 피해야한다. // 이런 문제가 있음. // 1. SIX = 6임. 그런데 six도 추가하고 싶다면? // 2. Number 열거형에서 3을 제외하고 싶다면? public enum NumberWrong { ONE, TWO, THREE, FOUR, FIVE, SIX; public int getCount() { return ordinal() + 1; } } ordinal()을 이용하려고 하는 상황을 가정해보자. 이 때 ..