언어
-
이펙티브 자바 Item 38 - 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라언어/Effective Java 2024. 6. 11. 09:31
열거 타입은 보통은 확장에 적합하지 않다. 확장할 수 있는 열거타입이 필요할 떄도 있는데, 연산 코드가 그 예시이다. 사용자 확장 연산을 추가할 수 있도록 열어주는 것이다. 열거 타입이 임의의 인터페이스를 구현하여 확장하면 된다. 인터페이스를 이용해 확장 가능 열거 타입처럼 만들어보기 public interface Operation{ double apply(double x, double y);} PLUS("+") { public double apply(double x, double y) { return x + y; } }, MINUS("-") { public double apply(double x, double y) { return x - y; } }, T..
-
이펙티브 자바 Item 37 - ordinal 인덱싱 대신 EnumMap을 사용하라언어/Effective Java 2024. 6. 7. 17:43
열거 타입의 ordinal을 배열의 인덱스로 사용하는 경우가 있다. 식물의 생애주기를 열거 타입으로 표현한 LifeCycle타입을 예로 들어보자 public class Plant { final String name; final LifeCycle lifeCycle; public Plant(String name, LifeCycle lifeCycle) { this.name = name; this.lifeCycle = lifeCycle; } @Override public String toString() { return name; }}public enum LifeCycle { ANNUAL, PERNNIAL, BIENNIAL} - Pl..
-
이펙티브 자바 Item 36- 비트 필드 대신 EnumSet을 사용하라언어/Effective Java 2024. 6. 7. 11:08
열거한 값들이 주로 집합으로 사용될 경우, 예전에는 상수에 서로 다른 2의 거듭제곱 값을 할당한 정수 열거 패턴을 사용해 왔다. public class StyleWithBitField { public static final int STYLE_BOLD = 1 위와 같이 비트별 OR를 사용해 여러 상수르 ㄹ하나의 집합으로 모을 수 있으며, 이 집합을 비트 필드라한다.하지만, 비트 필드 또한 정수 열거 상수이므로, 정수 열거 상수의 단점을 그대로 지니며, 추가로 다른 문제도 가진다.비트 필드 값이 그대로 출력되면, 단순한 정수 열거 상수를 출력할 때보다 해석하기 더 어렵다비트 필드 하나에 녹아 있는 모든 원소를 순회하기 까다롭다.최대 몇 비트가 필요한지 처음부터 예상하고 적절한 타입을 선택해야한다.E..
-
이펙티브 자바 Item 35 : ordinal 메서드 대신 인스턴스 필드를 사용하라언어/Effective Java 2024. 6. 7. 10:14
열거 타입 상수는 하나의 정수값에 대응되며, 모든 열거 타입은 해당 상수가 몇 번째 위치인지 반환하는 ordinal()메서드를 제공한다. ordinal()의 잘못 사용한 예 해당 코드는 상수 선언 순서를 바꾸는 순간 오작동하며, 이미 사용 중인 정수와 값이 같은 상수는 추가할 방법이 없다. 동작은 하지만 유지보수의 어려움이 있다! public enum Ensemble { SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTER, OCTET, DOUBLE_QUARTET, NONET, DECTET, TRIPLE_QUARTET; public int numberOfMusicians() { return ordinal() + 1; } 열거 타입 상수에..
-
이펙티브 자바 Item 34 - int 상수 대신 열거 타입을 사용하라언어/Effective Java 2024. 6. 5. 15:39
Java에서 열거 타입을 지원하기 전에는 아래와 같이 정수 상수를 한 묶음으로 선언하여 사용하였다.하지만 이런 '정수 열거 패턴'은 많은 단점들이 존재한다. public static final int APPLE_PIE = 0;public static final int APPLE_JAM = 1;public static final int GRAPE_PIE = 0;public static final int GRAPE_JAM = 1; 1. 타입 안전을 보장할 방법이 없으며 표현력이 좋지 않다. 위 코드에서 보는 것과 같이 APPLE_GRAPE_PIE와 GRAPE_PIE는 다른 접두어를 써서 겉보기에는 다른 곳에서 사용할 것을 알 수 있지만 컴파일러 입장에서는 둘다 정수 0이기 때문에 APPLE_PIE가 사용되..
-
이펙티브 자바 Item 33 - 타입 안전 이종 컨테이너를 고려하라언어/Effective Java 2024. 6. 5. 11:42
타입 안전 이종 컨테이너 패턴 컨테이너 대신 키를 매개변수화한 다음, 컨테이너에 값을 넣거나 뺄 때 매개변수화 키를 함께 제공하면 제네릭 타입 시스템이 값의 타입이 키와 같음을 보장해준다. 이러한 설계 방식을 타입 안전 이종 컨테이너 패턴이라 한다. public class Favorites { public void putFavorite(Class type, T instance); public T getFavorite(Class type);}... // 코드생략public static void main(String[] args) { Favorites favorites = new Favorites(); favorites.putFavorite(String.class,"morning..
-
이펙티브 자바 Item 32 - 제네릭과 가변인수를 함께 쓸 때는 신중하라언어/Effective Java 2024. 6. 5. 10:28
가변인수 ...은 메서드를 사용하는 클라이언트에서 파라미터를 몇개 보낼지 선택하는 것 아래와 같이 가변인수와 제네릭을 함께 사용하면 타입 안정성 문제가 발생한다.static void dangerous(List... stringLists) { List intList = List.of(42); Object[] objects = stringLists; objects[0] = intList; // 힙 오염 발생 String s = stringLists[0].get(0); // ClassCastException } 제네릭은 성격상 배열과 궁합이 별로다.제네릭 타입의 배열을 정의한는 걸 컴파일러가 막아준다.그러나 가변인자는 내부적으로 제네릭의 배열이 만들어지는..
-
이펙티브 자바 Item31 한정적 와일드 카드를 사용해 API의 유연성을 높여라언어/Effective Java 2024. 6. 5. 09:42
한정적 와일드 카드를 써야 하는 이유 상속을 고려해서 제네릭을 짜야할 때 한정적 와일드 카드를 써야한다. 제네릭은 기본적으로 불공변이다. List와 List은 서로 아무런 관계가 없는 타입이다.때로는 이러한 불공변을 보다 더 유연한 방식으로 사용해야할 때가 있다. 이때 와일드 카드를 사용한다.public void pushAll(Iterable src) { for (E e : src) { push(e); }}위 코드는 아무런 문제가 없다만, Stack을 Number로 선언하고, ArrayList를 매개변수로 전달하면, Number가 Integer의 부모이므로, 논리적으로 될 것 같지만 동작하지 않는다.이럴때 한정적 와일드 카드로 해결할 수 있다.public void pushAll(Iterabl..