핵심 내용 런타임 에러를 발생시키는 oridinal 메소드를 사용하지 말고, EnumMap을 사용하라. 다차원일 경우 EnumMap을 사용하라. 올바르지 않는 방법 : oridinal()을 배열 인덱스로 사용 public class Plant { enum LifeCycle { ANNUAL, PERNNIAL, BIENNIAL} final String name; final LifeCycle lifeCycle; public Plant(String name, LifeCycle lifeCycle) { this.name = name; this.lifeCycle = lifeCycle; } @Override public String toString() { return name; } } pub..
비트 필드 열거 상수 : 각 상수에 서로 다른 2의 거듭 제곱 값을 할당한 정수 열거 패턴(아이템 34) 열거한 값들이 집합으로 사용될 경우, 예전에는 비트 필드 열거 상수를 사용하였다. class Text { public static final int STYLE_BOLD = 1
이 아이템은 정말 제목이 전부이다.. 정말 ordinal은 쳐다보지 말고 인스턴스 필드를 사용하면 된다. ordinal을 사용할 경우 : 유지보수 극악 public enum Ensemble { SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET; public int numberOfMusicians() { return ordinal() + 1; } } 상수의 선언 순서를 변경하면 오동작.. 이미 사용 중인 정수와 값이 같은 상수 추가 불가능.. 값이 비어있는 중간 상수 추가 불가능.. 결론적으로 유지보수에 적합하지 않다. 인스턴스 필드에 저장하자 public enum Ensemble { SOLO(1), DUET(2), TRIO(..
6장 열거 타입과 어노테이션 Java에는 특수한 목적의 참조 타입이 두 가지 있다. 하나는 클래스의 일종인 enum, 다른 하나는 인터페이스의 일종인 어노테이션이다. 이번 6장은 두 가지 타입을 잘 사용하는 방법에 대해 다룬다 ! 이번 아이템은 열거 타입의 장점과 열거 타입을 "잘" 작성하는 방법에 대해 다룬다. 정수 열거 패턴 : 단점이 너무 많은 .. 🚩 단점 ◾ 타입 안전을 보장할 수 없다. ◾ 가독성이 좋지 않다. ◾ namespace를 지원하지 않는다. : 이름 충돌을 방지하기 위해서는 접두어를 써야 한다. ◾ 수정될 경우, 클라이언트 측에서 컴파일해야 한다. : 클라이언트 파일에 남겨지기 때문에, 상수의 값이 바뀌면 클라이언트도 반드시 컴파일해야 하며, 컴파일 하지 않을 경우 이상 동작을 할 ..
어려워요..꼭 다시 복습해야 하는 아이템 Class 객체 Java에서는 각 타입의 Class 객체를 key로 사용할 수 있다. 이 Class 객체는 제네릭으로 정의되어 있어서 타입에 따라 구체화될 수 있다. 예를 들어, String 클래스의 Class 객체는 Class 타입을 갖게 되며, Integer 클래스의 Class 객체는 Class 타입을 갖게 된다. 이렇게 Class 객체를 매개변수화한 키로 사용할 수 있는 이유는 Class 클래스 자체가 제네릭으로 정의되어 있기 때문이다. Class 클래스는 타입 매개변수 T를 가지고 있어서 실제 타입에 따라서 Class 형태로 사용된다. 이러한 Class 타입의 객체를 매개변수로 받는 메소드를 정의할 수 있다. 이 메소드는 특정 타입의 Class 객체를 전달..
"제네릭 가변인수 메소드를 사용하든, List로 대체를 하든, 항상 타입 안정성을 보장하는 코드를 작성하자 !" 가변인수 메소드 varargs 메소드는 여러 가지 이유로 유용하다. 1. 유연성 : 개발자가 원하는 만큼의 인수를 전달할 수 있다. 이는 코드 작성에 더 큰 유연성을 제공하며, 메소드 오버로딩을 줄일 수 있다. 2. 코드 간결성 : 가변인수를 사용하면 배열을 명시적으로 생성하고 초기화하는 번거로움을 줄일 수 있다. 이는 코드를 간결하고 가독성을 좋게 한다. 이 아이템에서 다룬 모든 문제의 시작은 가변 varargs 메소드가 내부적으로 배열을 만드는 메커니즘을 갖기 때문이다 .. 함께하기엔 너무 다른 배열의 공변성과 타입 매개변수의 불공변성.. 제네릭의 유연성도 가지고 싶고, 가변 varargs..
불공변 방식은 유연하지 못하다. 불공변은 쉽게 말하면, 하위 타입이 상위 타입으로 대체될 수 없는 것을 말한다. 즉, 제네릭 타입 매개변수가 서로 다른 타입일 경우, 컴파일 에러가 발생한다. 따라서 타입 안정성을 보장하지만, API 유연성이 제한된다. 예시 코드 public class Stack { public Stack() { ... } public void push(E e) { ... } public void pop() { ... } public boolean isEmpty() { ... } public void pushAll(Iterable src) { // 유연성 제한 for (E e : src) push(e); } public void popAll(Collection dst) { // 유연성 제..
이번 아이템의 핵심은 “제네릭 클래스 이외에도 제네릭 메소드 또한 만들 수 있다”이다. 책에서는 이에 대해 제네릭 메소드 작성법을 설명하는 것이다. 핵심을 놓치지 말자.. 제네릭 public class Student { static T name; } static 변수는 제네릭을 사용할 수 없다. 왜냐하면 Student 클래스가 인스턴스 되기 전에 static은 메모리에 올라가는데, 이때 name의 타입인 T가 결정되지 않기 때문이다. static 메소드에도 제네릭을 사용하면 에러가 발생하는데, static 변수와 마찬가지로 Student 클래스가 인스턴스화 되기 전에 메모리에 올라가는데 T의 타입이 정해지지 않기 때문이다. 그러나 제네릭 메소드는 static이 가능하다. 어떻게 가능하냐면, 제네릭 메소드..