Book
-
Item 37. ordinal 인덱싱 대신 EnumMap을 사용하라Book/Effective Java 3E 2023. 2. 24. 19:00
package effectivejava.chapter6.item37; import java.util.*; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toSet; // EnumMap을 사용해 열거 타입에 데이터를 연관시키기 // 식물을 아주 단순하게 표현한 클래스 class Plant { enum LifeCycle { ANNUAL, PERENNIAL, BIENNIAL } final String name; final LifeCycle lifeCycle; Plant(String name, LifeCycle lifeCycle) { this.name = name; this.lifeCyc..
-
Item 35. ordinal 메서드 대신 인스턴스 필드를 사용하라Book/Effective Java 3E 2022. 12. 29. 21:00
모든 열거 타입은 해당 상수가 그 열거 타입에서 몇 번째 위치인지를 반환하는 ordinal이라는 메서드를 제공합니다. 다음 코드는 합주단의 종류를 연주자가 1명인 솔로(solo)부터 10명인 디텍트(dectet)까지 정의한 열거 타입입니다. public enum Ensemble { SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET; public int numberOfMusicians() { return ordinal() + 1; } } 동작은 하지만 유지보수하기가 끔찍한 코드입니다. 상수 선언 순서를 바꾸는 순간 numberOfMusicians가 오동작하며, 이미 사용 중인 정수와 값이 같은 상수는 추가할 방법이 없습니다. ..
-
Item 34. int 상수 대신 열거 타입을 사용하라Book/Effective Java 3E 2022. 12. 28. 23:20
열거 타입은 일정 개수의 상수 값을 정의한 다음, 그 외의 값은 허용하지 않는 타입입니다. 사계절, 태양계의 행성, 카드게임의 카드 종류 등이 좋은 예입니다. 자바에서 열거 타입을 지원하기 전에는 다음 코드처럼 정수 열거 패턴을 사용했습니다. // 코드 34-1 정수 열거 패턴 - 상당히 취약하다! public static final int APPLE_FUJI = 0; public static final int APPLE_PIPPIN = 1; public static final int APPLE_GRANNY_SMITH = 2; 정수 열거 패턴(int enum pattern) 기법은 타입 안전을 보장할 방법이 없으며 표현력도 좋지 않습니다. 또한 상수의 값이 바뀌면 클라이언트도 반드시 다시 컴파일해야 합니..
-
Item 33. 타입 안전 이종 컨테이너를 고려하라Book/Effective Java 3E 2022. 12. 23. 21:00
Set에는 원소의 타입을 뜻하는 단 하나의 타입 매개변수만 있으면 되며, Map에는 키와 값의 타입을 뜻하는 2개만 필요합니다. 데이터베이스의 경우에는 행(row)에 해당하는 임의 개수의 열(column)이 필요합니다. 이런 경우, 키를 매개변수화한 다음 컨테이너에 값을 넣거나 뺄 때 매개변수화한 키를 함께 제공하면 됩니다. 이러한 설계 방식을 타입 안전 이종 컨테이너 패턴(type safe heterogeneous container pattern)이라 합니다. 다음은 간단한 예로 타입별로 즐겨 찾는 인스턴스를 저장하고 검색할 수 있는 Favorites 클래스입니다. 각 타입의 Class 객체를 매개변수화한 키 역할로 사용합니다. package effectivejava.chapter5.item33; im..
-
Item 32. 제네릭과 가변인수를 함께 쓸 때는 신중하라Book/Effective Java 3E 2022. 12. 20. 06:00
가변인수(varargs)는 메서드에 넘기는 인수의 개수를 클라이언트가 조절할 수 있게 해주는데, 구현 방식에 허점이 있습니다. 가변인수 메서드를 호출하면 가변인수를 담기 위한 배열이 자동으로 하나 만들어집니다. 그런데 내부로 감춰야 했을 이 배열을 그만 클라이언트에 노출하는 문제가 생겼습니다. 그 결과 varargs 매개변수에 제네릭이나 매개변수화 타입이 포함되면 알기 어려운 컴파일 경고가 발생합니다. 다음 메서드에서는 형변환하는 곳이 보이지 않는데도 인수를 건네 호출하면 ClassCastException이 발생합니다. 컴파일러가 생성한 (보이지 않는) 형변환이 숨어 있기 때문입니다. 이처럼 타입 안전성이 깨지니 제네릭 varargs 배열 매개변수에 값을 저장하는 것은 안전하지 않습니다. package ..
-
Item 31. 한정적 와일드카드를 사용해 API 유연성을 높이라Book/Effective Java 3E 2022. 11. 19. 10:15
Item 29의 Stack 클래스에 일련의 원소를 스택에 넣는 pushAll 메서드와 짝을 이루는 popAll 메서드를 추가해야 한다고 해봅시다. package effectivejava.chapter5.item31; import java.util.*; // 와일드카드 타입을 이용해 대량 작업을 수행하는 메서드를 포함한 제네릭 스택 public class Stack { private E[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; // 코드 29-3 배열을 사용한 코드를 제네릭으로 만드는 방법 1 // 배열 elements는 push(E)로 넘어온 E 인스턴스만 담는다. // 따라서 타입 안..
-
Item 30. 이왕이면 제네릭 메서드로 만들라Book/Effective Java 3E 2022. 11. 12. 11:55
클래스와 마찬가지로 메서드도 제네릭으로 만들 수 있습니다. 매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제네릭입니다. 예컨대 Collections의 '알고리즘' 메서드(binarySearch, sort 등)는 모두 제네릭입니다. 다음은 두 집합의 합집합을 반환하는, 문제가 있는 메서드입니다(컴파일은 되지만 경고가 두 개 발생합니다). // 코드 30-1 로 타입 사용 - 수용 불가! (Item 26) public static Set union(Set s1, Set s2) { Set result = new HashSet(s1); result.addAll(s2); return result; } 경고를 없애려면 타입 안전하게 만들어야 합니다. (타입 매개변수들을 선언하는) 타입 매개변수 목록은 메서드의..