728x90
반응형

전체 글 168

[Effective Java] 아이템 33. 타입 안정 이종 컨테이너를 고려하라.

🎯 아이템 33. 타입 안정 이종 컨테이너를 고려하라. ⭐ 이종 컨테이너 패턴(type safe heterogeneous container) click here. 컬렉션 API로 대표되는 일반적인 제네릭 형태에서는 한 컨테이너가 다룰 수 있는 타입 매개변수의 수가 고정되어 있다. 하지만 컨테이너 자체가 아닌 키를 타입 매개변수로 바꾸면 이런 제약이 없는 타입 안전 이종 컨테이너를 만들 수 있다. 타입 안전 이종 컨테이너는 Class를 키로 쓰며, 이런 식으로 Class 객체를 타입 토큰이라 한다. 또한, 직접 구현한 키 타입도 쓸 수 있다. 예컨대 데이터베이스의 행을 표현한 DatabaseRow 타입에는 제네릭 타입 Column를 키로 사용할 수 있다. public class Favorites { // ..

Java 2023.03.21

[Effective Java] 아이템 32. 제네릭과 가변인수를 함께 쓸 때는 신중하라.

🎯 아이템 32. 제네릭과 가변인수를 함께 쓸 때는 신중하라. 가변인수 메서드와 제네릭은 자바 5 때 함께 추가되었으니 서로 잘 어우러지리라 기대하겠지만, 슬프게도 그렇지 않다. 가변인수는 메서드에 넘기는 인수의 개수를 클라이언트가 조절할 수 있게 해주는데, 구현 방식에 허점이 있다. 제네릭과 가변인수를 혼용하면 타입 안정성이 깨진다! static void dangerous(List... stringLists) { List intList = List.of(42); Object[] objects = stringLists; objects[0] = intList; // 힙 오염 발생 String s = stringLists[0].get(0); // ClassCastException } 위 처럼 타입 안전성이 ..

Java 2023.03.21

[Effective Java] 아이템 31. 한정적 와일드카드를 사용해 API 유연성을 높이라.

🎯 아이템 31. 한정적 와일드카드를 사용해 API 유연성을 높이라. 매개변수화 타입은 불공변이다. 즉 서로 다른 타입 Type1과 Type2가 있을 때 List은 List의 하위 타입도 상위 타입도 아니다. 즉, List은 List가 하는 일을 제대로 수행하지 못하니 하위 타입이 될 수 없다. ( 리스코프 치환 원칙 에 어긋난다. ) 와일드카드 타입을 사용하지 않은 pushAll 메서드 - 결함이 있다! // Stack의 public API public void pushAll(Iterable src){ for (E e : src) { push(e); } } 언뜻보면 컴파일도 되고 완벽해 보이지만 결함이 있다. public final class Integer extends Number implements..

Java 2023.03.21

[Effective Java] 아이템 30. 이왕이면 제네릭 메서드로 만들라.

🎯 아이템 30. 이왕이면 제네릭 메서드로 만들라. 제네릭 타입과 마찬가지로, 클라이언트에서 입력 매개변수와 반환값을 명시적으로 형변환해야 하는 메서드보다 제네릭 메서드가 더 안전하며 사용하기도 쉽다. 로 타입 사용 - 수용 불가! public static Set union(Set s1, Set s2) { Set result = new HashSet(s1); result.addAll(s2); return result; } 컴파일은 되지만 Raw use of parameterized class 'Set', Unchecked call to 'addAll(Collection

Java 2023.03.21

[Effective Java] 아이템 29. 이왕이면 제네릭 타입으로 만들라.

🎯 아이템 29. 이왕이면 제네릭 타입으로 만들라. 새로운 타입을 설계할 때는 형변환 없이도 사용할 수 있도록하라. 그렇게 하려면 제네릭 타입으로 만들어야 할 경우가 많다. 기존 타입 중 제네릭이었어야 하는 게 있다면 제네릭 타입으로 변경하자. 기존 클라이언트에는 아무 영향을 주지 않으면서, 새로운 사용자를 훨씬 편하게 해주는 길이다. Object 기반 스택 - 제네릭이 절실한 강력 후보!⭐ 지금 상태에서는 클라이언트가 스택에서 꺼낸 객체를 형변환해야 하는데, 이때 런타임 오류가 날 위험이 있다. public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACI..

Java 2023.03.21

[Effective Java] 아이템 28. 배열보다는 리스트를 사용하라.

🎯 아이템 28. 배열보다는 리스트를 사용하라. 배열과 제네릭 타입에는 중요한 차이가 두 가지 있다. 1️⃣ 배열은 공변이지만, 제네릭은 불공변이다. Sub가 Super의 하위 타입이라면 배열 Sub[]는 배열 Super[]의 하위 타입이 된다. 반면, 서로 다른 타입 Type1, Type2가 있을 때, List은 List의 하위 타입도 아니고 상위 타입도 아니다. 어느 쪽이든 Long용 저장소에 String을 넣을 수는 없다. 다만 배열에서는 그 실수를 런타임에야 알게 되지만, 리스트를 사용하면 컴파일할 때 바로 알 수 있다. 2️⃣ 배열은 실체화(reify)된다. 배열은 런타임에도 자신이 담기로 한 원소의 타입을 인지하고 확인한다. 그래서 위 코드에 보듯 Long배열에 String을 넣으려 하면 Ar..

Java 2023.03.20
728x90
반응형