본문 바로가기
반응형

Java/Effective Java 3E61

[이펙티브자바 3판] ITEM32. 제네릭과 가변인수를 함께 쓸 때는 신중하라 이번장의 핵심은... 가변 인수와 제네릭은 궁합이 좋지 않다 가변 인수 기능은 배열을 노출하여 추상화가 완벽하지 못하고, 배열과 제네릭의 타입 규칙이 서로 다르기 때문이다 제네릭 varargs 매개변수는 타입 안전하지는 않지만 허용된다 메서드에 제네릭 varargs 매개변수를 사용하고자 한다면, 먼저 그 메서드가 타입 안전한지 확인한 다음 @Safevarargs 애너테이션을 달아 사용하는 데 불편함이 없게끔 하자. 타입 안정성이 깨지니 제네릭 varargs 배열 매개변수에 값을 저장하는 것은 안전하지 않다 // 제네릭과 varargs(가변인수)를 혼용하면 타입 안정성이 깨진다 static void dangerous(List ... stringLists) { List inList = List.of(42);.. 2020. 10. 23.
[이펙티브자바 3판] ITEM31. 한정적 와일드카드를 사용해 API 유연성을 높이라 이번장의 핵심은... 조금 복잡하더라도 와일드카드 타입을 적용하면 API가 훨씬 유연해진다 그러니 널리 쓰일 라이브러리를 작성한다면 반드시 와일드카드 타입을 적절히 사용해줘야 한다 PECS 공식을 기억하자 즉, 생산자(producer)는 extends를 소비자(consumer)는 super를 사용한다 Comparable과 Comparator는 모두 소비자라는 사실도 잊지 말자 매개변수화 타입은 불공변 즉, 서로 다른 타입 Type1, Type2가 있을 때, List은 List의 상위 타입도 하위 타입도 아니다 때론 불공변 방식보다 유연한 무언가가 필요하다 public class Stack { public Stack(); public void push(E e); public E pop(); public b.. 2020. 10. 18.
[이펙티브자바 3판] ITEM30. 이왕이면 제네릭 메서드로 만들어라 이번장의 핵심은... 제네릭 타입과 마찬가지로, 클라이언트에서 입력 매개변수와 반환 값을 명시적으로 반환해야 하는 메서드보다 제네릭 메서드가 더 안전하며 사용하기도 쉽다 타입과 마찬가지로, 메서드도 형변환 없이 사용할 수 있는 편이 좋으며, 많은 경우 그렇게 하려면 제네릭 메서드가 되어야 한다 역시 타입과 마찬가지로, 형변환을 해줘야 하는 기존 메서드는 제네릭하게 만들자 기존 클라이언트는 그대로 둔 채 새로운 사용자의 삶을 훨씬 편하게 만들어줄 것이다 제네릭 메서드 매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제네릭 예를 들어, Collections의 '알고리즘 메서드' (binarySearch, sort 등) 모두 제네릭 // 로 타입 사용 - 수용 불가 public static Set unio.. 2020. 10. 17.
[이펙티브자바 3판] ITEM29. 이왕이면 제네릭 타입으로 만들어라 이번장의 핵심은... 클라이언트에서 직접 형 변환해야 하는 타입보다 제네릭 타입이 더 안전하고 쓰기 편하다 그러니 새로운 타입을 설계할 때는 형 변환 없이도 사용할 수 있도록 하라 기존 타입 중 제네릭이었어야 하는 게 있다면 제네릭 타입으로 변경하자 기존 클라이언트에는 아무 영향을 주지 않으면서, 새로운 사용자를 훨씬 편하게 해주는 길이다 제네릭 타입으로 만들자 제네릭 타입을 새로 만드는 일은 조금 어렵지만 배워두면 그만한 값어치를 충분히 한다 // 제네릭이 절실한 강력 후보! (Object 기반 스택) public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CA.. 2020. 10. 15.
[이펙티브자바 3판] ITEM28. 배열보다는 리스트를 사용하라 이번장의 핵심은... 배열과 제네릭에는 매우 다른 타입 규칙이 적용된다 배열은 공변이고 실체화되는 반면, 제네릭은 불공변이고 타입 정보가 소거된다 배열은 런타임에는 타입 안전하지만 컴파일 타임에는 아니다 제네릭은 반대이다 따라서 둘을 섞어 쓰기는 쉽지 않다. 섞어 쓰다 에러가 나면 가장 먼저 배열을 리스트로 대체하는 방법을 적용해보자 배열 vs 제네릭 타입 1. 배열은 공변이다 Sub가 Super의 하위 타입이라면 배열 Sub[]는 배열 Super[]의 하위 타입이 된다 (즉, 공변이란 함께 변한다는 뜻이다) 반면, 제네릭은 불공변이다 즉, 서로 다른 타입 Type1, Type2가 있을 때, List은 List의 하위 타입도 아니고 상위 타입도 아니다 제네릭에 문제가 있다고 생각할 수 있지만, 사실문제가.. 2020. 10. 14.
[이펙티브자바 3판] ITEM27. 비검사 경고를 제거하라 이번장의 핵심은... 비검사 경고는 중요하니 무시하지 말자 모든 비검사 경고는 런타임에 ClassCastException을 일으킬 수 있는 잠재적 가능성을 뜻하니 최선을 다해 제거하라 경고를 없앨 방법을 찾지 못하겠다면, 그 코드가 타입 안정함을 증명하고 가능한 한 범위를 좁혀 @SuppressWarnings("unchecked") 애너테이션으로 경고를 숨겨라 그런 다음 경고를 숨기기로 한 근거를 주석으로 남겨라 비검사 경고 제네릭을 사용하면 수많은 컴파일러 경고가 나온다 ex) 비검사 형변환 경고, 비검사 메서드 호출 경고.. 등등 제네릭에 익숙해질수록 경고 수가 줄어들 것이다 Set exaltation = new HashSet(); //-> 컴파일러가 알려준 타입 매개변수를 명시하지 않고 만으로 해결.. 2020. 10. 13.
[이펙티브자바 3판] ITEM26. 로(raw) 타입은 사용하지 말라 이번장의 핵심은... 로 타입을 사용하면 런타임 예외가 일어날 수 있으니 사용하면 안 된다 로 타입은 제네릭이 도입되기 이전 코드와의 호환성을 위해 제공될 뿐 Set는 어떤 타입의 객체도 저장할 수 있는 매개변수화 타입이고, Set는 모종의 타입 객체만 저장할 수 있는 와일드카드 타입이다 그리고 이들의 로 타입인 Set은 제내릭 타입 시스템에 속하지 않는다 Set와 Set은 안전하지만, 로 타입인 Set은 안전하지 않다 제네릭 타입 (제네릭 클래스, 혹은 제네릭 인터페이스) 클래스와 인터페이스 선언에 타입 매개변수를 쓰는 것 List → String인 리스트를 뜻하는 매개변수화 타입 제네릭 타입 하나 정의하면 그에 딸린 raw type도 함께 정의된다 Raw Type 제네릭 타입에서 타입 매개변수를 전혀.. 2020. 10. 8.
반응형