Effective JAVA
-
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 32. 제네릭과 가변인수를 함께 쓸 때는 신중하라Book/Effective Java 3E 2022. 12. 20. 06:00
가변인수(varargs)는 메서드에 넘기는 인수의 개수를 클라이언트가 조절할 수 있게 해주는데, 구현 방식에 허점이 있습니다. 가변인수 메서드를 호출하면 가변인수를 담기 위한 배열이 자동으로 하나 만들어집니다. 그런데 내부로 감춰야 했을 이 배열을 그만 클라이언트에 노출하는 문제가 생겼습니다. 그 결과 varargs 매개변수에 제네릭이나 매개변수화 타입이 포함되면 알기 어려운 컴파일 경고가 발생합니다. 다음 메서드에서는 형변환하는 곳이 보이지 않는데도 인수를 건네 호출하면 ClassCastException이 발생합니다. 컴파일러가 생성한 (보이지 않는) 형변환이 숨어 있기 때문입니다. 이처럼 타입 안전성이 깨지니 제네릭 varargs 배열 매개변수에 값을 저장하는 것은 안전하지 않습니다. package ..
-
Item 27. 비검사 경고를 제거하라Book/Effective Java 3E 2022. 11. 8. 23:00
제네릭을 사용하기 시작하면 수많은 컴파일러 경고를 보게 될 것입니다. 비검사 형변환 경고, 비검사 메서드 호출 경고, 비검사 매개변수화 가변인수 타입 경고, 비검사 변환 경고 등입니다. 대부분의 비검사 경고는 쉽게 제거할 수 있습니다. 할 수 있는 한 모든 비검사 경고를 제거하라 // warning 발생(javac 명령줄 인수에 -Xlint:uncheck 옵션 추가) Set exaltation = new HashSet(); // 비검사 경고 제거 Set exaltation = new HashSet(); 모두 제거한다면 그 코드는 타입 안정성이 보장됩니다. 즉, 런타임에 ClassCastException이 발생할 일이 없고, 잘 동작하리라 확신할 수 있습니다. @SuppressWarnings("unchec..
-
Item 21. 인터페이스는 구현하는 쪽을 생각해 설계하라Book/Effective Java 3E 2022. 10. 29. 09:30
자바 8에서는 핵심 컬렉션 인터페이스들에 다수의 디폴트 메서드가 추가되었습니다. 주로 람다(7장 참조)를 활용하기 위해서입니다. 자바 라이브러리의 디폴트 메서드는 코드 품질이 높고 범용적이라 대부분 상황에서 잘 작동합니다. 하지만 생각할 수 있는 모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하기란 어려운 법입니다. // 코드 21-1 자바8의 Collection 인터페이스에 추가된 디폴트 메서드 default boolean removeIf(Predicate
-
Item 12. toString을 항상 재정의하라Book/Effective Java 3E 2022. 10. 18. 21:30
toString의 일반 규약에 따르면 '간결하면서 사람이 읽기 쉬운 형태의 유익한 정보'를 반환해야 합니다. 또한 toString의 규약은 "모든 하위 클래스에서 이 메서드를 재정의하라"고 합니다. 실전에서 toString은 그 객체가 가진 주요 정보 모두를 반환하는 게 좋습니다. 하지만 객체가 거대하거나 객체의 상태가 문자열로 표현하기에 적합하지 않다면 요약 정보를 담아야 합니다. toString을 구현할 때면 반환값의 포맷을 문서화할지 정해야 합니다. 전화번호나 행렬 같은 값 클래스라면 문서화하기를 권합니다. 포맷을 명시하면 그 객체는 표준적이고, 명확하고, 사람이 읽을 수 있게 됩니다. 포맷을 명시하기로 했다면, 명시한 포맷에 맞는 문자열과 객체를 상호 전환할 수 있는 정적 팩터리나 생성자를 함께 ..