Study/Effective Java
-
제네릭 - Item 31. 한정적 와일드카드를 사용해 API 유연성을 높이라Study/Effective Java 2023. 1. 10. 15:36
한정적 와일드카드를 사용해 API 유연성을 높이라 한정적 와일드카드 사용의 필요성 매개변수화 타입은 불공변이다. 즉, 서로 다른 타입 Type1과 Type2가 있을 때 List은 List의 하위 타입도 상위 타입도 아니다. 예를 들어, List은 List의 하위 타입이 아니다. 그 이유는 List이 List가 하는 일을 제대로 수행하지 못하기 때문이다. 이는 리스코프 치환원칙을 위배한다. 이렇게 매개변수화 타입은 불공변이지만, 때로는 유연하게 API를 설계해야 하는 상황이 있다. 대표적으로 public API를 설계할 때 필요하다. 한정적 와일드카드를 사용하지 않은 경우(1) - pushAll() public class Stack { private List list = new ArrayList(); pu..
-
제네릭 - item 30. 이왕이면 제네릭 메서드로 만들라Study/Effective Java 2023. 1. 5. 17:43
이왕이면 제네릭 메서드로 만들라 제네릭 메서드 public static Set union(Set s1, Set s2) { Set result = new HashSet(s1); result.addAll(s2); return result; } 클래스와 마찬가지로, 메서드도 제네릭으로 만들 수 있다. 제네릭 메서드 작성법은 제네릭 타입 작성법과 비슷하다. 위 메서드는 두 집합의 합집합을 반환하는 문제가 있는 메서드이다. 위 메서드는 컴파일은 되지만, 문제가 있는 메서드이다. 경고를 없애려면 이 메서드를 타입 안전하게 만들어야 한다. 메서드 선언에서의 세 집합(입력 2개, 반환 1개)의 원소 타입을 타입 매개변수로 명시하고, 메서드 안에서도 이 타입 매개변수만 사용하게 수정하면 된다. public static ..
-
제네릭 - 아이템 29. 이왕이면 제네릭 타입으로 만들라Study/Effective Java 2023. 1. 5. 14:07
이왕이면 제네릭 타입으로 만들라 제네릭 타입의 필요성 public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { ensureCapacity(); elements[size++] = e; } public Object pop() { if (size == 0) { throw new EmptyStackException(); } Object result = elements[--si..
-
제네릭 - 아이템 28. 배열보다는 리스트를 사용하라Study/Effective Java 2023. 1. 4. 14:55
배열보다는 리스트를 사용하라 배열과 제네릭의 차이 1. 공변과 불공변 배열과 제네릭 타입에는 중요한 두 가지 차이가 있다. 첫 번째, 배열은 공변이다. 예를 들어, Sub가 Super의 하위 타입이라면 배열 Sub[]는 배열 Super[]의 하위 타입이 된다. 즉, 같이 변한다는 의미이다. 반면, 제네릭은 불공변이다. 즉, 서로 다른 타입 Type1과 Type2가 있을 때, List은 List의 하위 타입도 아니고 상위 타입도 아니다. Object[] objectArray = new Long[1]; objectArray[0] = "타입이 달라 넣을 수 없다."; // ArrayStoreException을 던짐 Long용 저장소에 String을 넣을 수는 없다. 배열에서는 이러한 문제점을 런타임에야 알게 ..
-
제네릭 - 아이템 27. 비검사 경고를 제거하라Study/Effective Java 2023. 1. 4. 10:58
비검사 경고를 제거하라 비검사 경고란? 제네릭을 사용하기 시작하면 수많은 컴파일러 경고를 보게 될 것이다. 비검사 형변환 경고, 비검사 메서드 호출 경고, 비검사 매개변수화 가변인수 타입 경고, 비검사 변환 경고 등이다. 즉, 비검사 경고란 컴파일러 경고와 동일한 의미이다. 비검사 경고의 예시 Set set = new HashSet(); 위 코드와 같이 구현체의 타입을 명확히 주지 않은 채로 HashSet 객체를 생성할 수 있다. Note: Recompile with -Xlint:unchecked for details. 그러면 컴파일러는 무엇이 잘못됐는지 위와 같이 친절하게 알려줄 것이다. Set set = new HashSet(); 위 코드와 같이 다이아몬드 연산자()를 붙여주면 타입을 추론할 수 있으..
-
제네릭 - 아이템 26. 로 타입은 사용하지 말라Study/Effective Java 2023. 1. 3. 14:49
로 타입은 사용하지 말라 제네릭이란? 클래스와 인터페이스 선언에 타입 매개변수가 사용되면, 이를 제네릭 클래스 혹은 제네릭 인터페이스라고 부르며 이를 통틀어 제네릭 타입이라고 한다. 각각의 제네릭 타입은 일련의 매개변수화 타입을 정의한다. 먼저 클래스의 이름이 나오고, 바로 옆에 꺾쇠괄호 안에 실제 타입 매개변수들을 나열한다. 예를 들어, List은 원소의 타입이 String인 리스트를 뜻하는 매개변수화 타입이다. 여기서 String은 정규 타입 매개변수 E에 해당하는 실제 타입 매개변수이다. 로 타입이란? 제네릭 타입을 하나 정의하면 그에 딸린 로 타입도 함께 정의된다. 로 타입이란 제네릭 타입에서 타입 매개변수를 전혀 사용하지 않을 때를 말한다. 예를 들어, List의 로 타입은 List이다. 로 타..