Effective Java73 [Effective Java] 아이템31 한정적 와일드카드를 사용해 API 유연성을 높이라 제네릭은 불공변이다. 하지만 때로는 불공변 방식보다 유연하게 사용해야 할 수 있다. 이때 사용하는 것이 한정적 와일드카드이다. ■ Stack 예시 public class Stack{ public Stack(); public void push(E e); public E pop(); public boolean isEmpty(); } 여기에 일련의 원소를 스택에 넣는 메서드를 추가해야 한다고 해보자. public void pushAll(Iterable src){ for(E e : src) push(e); } 위의 메서드에서 Stack로 선언한 후 pushAll(intValue)를 호출하면 Integer는 Number의 하위 타입이지만 불공변이기 때문에 오류가난다. 이를 해결하기 위해서 사용하는 것이 한정적 와.. 2021. 5. 30. [Effective Java] 아이템30 이왕이면 제네릭 메서드로 만들라 클래스와 마찬가지로 메서드도 제네릭으로 만들 수 있다. 매개변수화 타입을 받는 정적 유틸리티 메서드는 보통 제네릭이다. 예를 들어 Collections의 알고리즘 메서드(binarySearch, sort 등)는 모두 제네릭이다. ■ 로 타입 사용 - 타입 안전성 보장 불가 아래 코드는 컴파일은 되지만 경고가 두 개 발생 한다. public static Set union(Set s1, Set s2) { Set result = new HashSet(s1); result.addAll(s2); return result; } 타입 안전성을 보장하기 위해서 원소 타입을 타입 매개변수로 명시하고 메서드 안에서도 이 타입 매개변수만 사용하게 수정하면 된다. 이 때 타입 매개변수들을 선언하는 타입 매개변수 목록은 메서드.. 2021. 5. 29. [Effective Java] 아이템29 이왕이면 제네릭 타입으로 만들라 Object를 사용할 경우 클라이언트가 매번 형변환을 해야하고 그 과정에서 Runtime 에러가 발생하는 것을 막기 위해 이왕이면 제네릭타입으로 만들자. ■ Object기반 스택 이 클래스는 제네릭 타입이어야한다. 스택에서 꺼낸 객체를 형변환할 때 런타임 오류가 발생할 수 있다. 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(); .. 2021. 5. 23. [Effective Java] 아이템28 배열보다는 리스트를 사용하라 ■ 배열과 제네릭 차이점 1. 배열은 공변이다. Sub가 Super의 하위 타입이라면 배열 Sub[]는 배열 Super[]의 하위 타입이다. 즉, 함께 변한다는 뜻이다. 반면에 제네릭은 불공변이다. List은 List의 하위 타입도 아니고 상위 타입도 아니다. 제네릭에 문제가 있다고 생각할 수 있지만 사실 문제가 있는건 배열이다. 리스트를 사용할 경우 컴파일 때 에러를 바로 알 수 있다. // 런타임 실패 Object[] objectArray = new Long[1]; objectArray[0] = "타입이 달라 넣을 수 없다."; // ArrayStoreException // 다음 코드는 문법에 맞지 않아 컴파일조차 되지 않음 List ol = new ArrayList(); // 호환되지 않는 타입이다.. 2021. 5. 23. [Effective Java] 아이템27 비검사 경고를 제거하라 ■ 비검사 경고 제네릭을 사용하면 수많은 컴파일러가 경고를 보게 될 것이다. 제네릭에 익숙해질수록 경고 수가 줄어들 것이다. Set exaltation = new HashSet(); //-> 컴파일러가 알려준 타입 매개변수를 명시하지 않고 만으로 해결가능 Set exaltation = new HashSet(); ■ 할 수 있는 한 모든 비검사 경고를 제거하라. 비검사 경고를 모두 제거하면 그 코드는 타입 안정성이 보장된다. 즉, 런타임에 ClassCastException이 발생할 일이 없다는 것 이다. ■ SuppressWarnings 경고를 제거할 수 없지만 타입 안전하다고 확실할 수 있으면 @SuppressWarnings("unchecked") 애너테이션을 달아 경고를 숨기자. 안전하다고 검증된 비검.. 2021. 5. 22. [Effective Java] 아이템26 로 타입은 사용하지 말라 ■ 로(raw) 타입이란? 로 타입이란 제네릭 타입에서 타입 매개변수를 전혀 사용하지 않은 때를 말한다. 예를 들어서 List의 로 타입은 List다. 제네릭 도입 이후에도 로 타입을 지원하는 이유는 기존 자바 버전과의 호환성 때문이다. 아래 컬렉션 예제 코드에서처럼 로 타입을 사용하여 객체를 저장 하면 컴파일 할 때는 에러가 발생하지 않는다. 그리고 런타임 때 저장된 객체를 꺼내면서 오류가 발생한다. 오류는 컴파일 시점에 발견하는 것이 좋다. //로 타입으로 인스턴스 저장 private final Collection stamps = ...; stamps.add(new Coin()); //데이터 꺼낼 때 오류 발생 for(Iterator i = stamps.iterator(); i.hasNext();){.. 2021. 3. 8. 이전 1 ··· 5 6 7 8 9 10 11 ··· 13 다음