Language
-
[Effective Java] 아이템35: ordinal 메서드 대신 인스턴스 필드를 사용하라Language/Java 2022. 8. 15. 12:01
✔️ ordinal 메서드란? 대부분의 열거 타입 상수는 하나의 정숫값에 대응된다. 그리고 모든 열거 타입은 해당 상수가 그 열거 타입에서 몇 번째 위치인지를 반환하는 메서드를 제공하는데, 이 메서드가 ordinal 메서드다. ✔️ ordinal의 잘못된 사용 언뜻 보면 굉장히 편리한 메서드처럼 보이고, 이 메서드를 이용하고 싶은 유혹에 빠지기 쉽다. 하지만 아이템 이름에서도 알 수 있듯이 사용하지 않는 것이 좋다. 연주자가 1명인 솔로(solo)부터 10명인 디텍트(dectet)까지 정의한 열거 타입 예제를 보자. public enum Ensemble { SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET; public in..
-
[Effective Java] 아이템34: int 상수 대신 열거 타입을 사용하라Language/Java 2022. 8. 11. 19:31
✔️ 열거 타입 (Enum Type) 📌 열거 패턴의 한계 자바에서 열거 타입을 지원하기 전에는 정수 열거 패턴(int enum pattern)을 사용하곤 했다. public static final int APPLE_FUJI = 0; public static final int APPLE_PIPPIN = 1; public static final int APPLE_GRANNY_SMITH = 2; public static final int GRAPE_NAVEL = 0; public static final int GRAPE_TEMPLE = 1; public static final int GRAPE_BLOOD = 2; 정수 열거 패턴에는 단점이 많다. 타입 안전을 보장할 수 없다. 표현력이 좋지 않다. 정수 열거..
-
[Effective Java] 아이템33: 타입 안전 이종 컨테이너를 고려하라Language/Java 2022. 8. 10. 18:11
✔️ 타입 안전 이종 컨테이너 패턴 제네릭은 컬렉션과 단일원소 컨테이너에 흔히 쓰인다. 이때 매개변수화되는 대상은 원소가 아닌 컨테이너 자신이다. 따라서 하나의 컨테이너에서 매개변수화할 수 있는 타입의 수가 제한된다. 하지만 더 유연한 수단이 필요할 때도 종종 있다. 예를 들어, 데이터베이스의 행은 임의 개수의 열을 가질 수 있는데 모두 열을 타입 안전하게 이용할 수 있다면 멋질 것이다. Q. 하나의 컨테이너에서 매개변수화할 수 있는 타입 개수를 제한하지 않고 사용할 수 있는 방법은 없을까? 해법은 컨테이너 대신 키를 매개변수화한 다음, 컨테이너에 값을 넣거나 뺄 때 매개변수화한 키를 함께 제공하는 것이다. 이러한 설계 방식을 타입 안전 이종 컨테이너 패턴(type safe heterogeneous co..
-
[Effective Java] 아이템32: 제네릭과 가변인수를 함께 쓸 때는 신중하라Language/Java 2022. 8. 9. 19:31
✔️ 가변인수 메서드와 제네릭 가변인수(varargs, variable arguments) 메서드와 제네릭은 자바 5 때 함께 추가되었으니 서로 잘 어우러지리라 기대하겠지만, 그렇지 않다. 가변인수 메서드를 호출하면 가변인수를 담기 위한 배열이 자동으로 하나 만들어지며, 이 배열은 클라이언트에게 노출된다. 그 결과 varargs 매개변수에 제네릭이나 매개변수화 타입이 포함되면 알기 어려운 컴파일 경고가 발생한다. 제네릭과 varargs를 혼용하면 타입 안전성이 깨지게 된다. 따라서 제네릭 varargs 배열 매개변수에 값을 저장하는 것은 안전하지 않다. 그렇다면 제네릭 배열을 프로그래머가 직접 생성하는 건 허용하지 않으면서 제네릭 varargs 매개변수를 받는 메서드를 선언할 수 있게 한 이유는 무엇일까..
-
[Effective Java] 아이템31: 한정적 와일드카드를 사용해 API 유연성을 높이라Language/Java 2022. 8. 6. 09:34
아이템 28에서 이야기했듯 매개변수화 타입은 불공변(invariant)이다. 즉 서로 다른 타입 Type1과 Type2가 있을 때 List은 List의 하위 타입도 상위 타입도 아니다. 하지만 때론 불공변 방식보다 유연한 무언가가 필요하다. 유연성을 높이기 위해, 원소의 생산자(producer)나 소비자(consumer)용 입력 매개변수에 와일드카드 타입을 사용하자. ✔️ PECS 팩스(PECS) 란, producer-extends, consumer-super 를 의미한다. 매개변수화 타입 T가 생산자라면
-
[Effective Java] 아이템30: 이왕이면 제네릭 메서드로 만들라Language/Java 2022. 8. 6. 09:33
클래스와 마찬가지로 메서드도 제네릭으로 만들 수 있다. 📌 단순한 제네릭 메서드 두 집합의 합집합을 반환하는 메서드를 예시로 보자. 로 타입 사용 public static Set union(Set s1, Set s2) { Set result = new HashSet(s1); result.addAll(s2); return result; } 위의 코드는 컴파일은 되지만 경고가 두 개 발생한다. 경고를 없애기 위해서는, 메서드를 타입 안전하게 만들어야 한다. 세 집합의 원소 타입을 타입 매개변수로 명시하고, 메서드 안에서도 이 타입 매개변수만 사용하게 수정하자! 제네릭 메서드 public static Set union(Set s1, Set s2) { Set result = new HashSet(s1); res..
-
[Effective Java] 아이템29: 이왕이면 제네릭 타입으로 만들라Language/Java 2022. 8. 6. 09:32
아이템7에서 다룬 스택 코드는 원래 제네릭 타입이어야 마땅하다. 다음과 같이 타입 매개변수 E를 추가하고, Object를 적절한 타입 매개변수로 바꾸어준다. public class Stack { private E[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { // 컴파일 오류. 실체화 불가 타입으로는 배열을 만들 수 없다. elements = new E[DEFAULT_INITIAL_CAPACITY]; } public void push(E e) { ensureCapacity(); elements[size++] = e; } public E pop() { if (si..
-
[Effective Java] 아이템28: 배열보다는 리스트를 사용하라Language/Java 2022. 7. 30. 02:29
✔️ 배열 vs 제네릭 타입 1. 배열은 공변(covariant)인 반면, 제네릭은 불공변(invariant)이다. Sub가 Super의 하위 타입이라면 배열 Sub[]는 배열 Super[]의 하위 타입이 되지만, List은 List의 하위 타입도 아니고 상위 타입도 아니다. 2. 배열은 실체화(reify)된다. 배열은 런타임에도 원소의 타입을 확인한다. 즉, 런타임에 예외가 발생할 수 있다. 반면, 제네릭은 타입 정보가 런타임에는 소거된다. 원소 타입을 컴파일타임에만 검사하며 런타임에는 알 수조차 없다. 💡 위와 같은 차이로 인해, 배열과 제네릭은 잘 어우러지지 못한다. 예를 들어, 배열은 제네릭 타입(new List[]), 매개변수화 타입(new List[]), 타입 매개변수(new E[])로 사용할..