Posts [이펙티브자바] 아이템26-로 타입은 사용하지 말라
Post
Cancel

[이펙티브자바] 아이템26-로 타입은 사용하지 말라

로 타입

  • 로 타입이란 제네릭 타입 매개변수를 전혀 사용하지 않을 때를 말한다.
    • 예컨대 List<E> 의 로 타입은 List다.
  • 로 타입(타입 매개변수가 없는 제네릭 타입)을 쓰는 걸 언어 차원에서 막아 놓진 않았지만 절대로 써선 안된다.
    • 로 타입을 쓰면 제네릭을 안겨주는 안정성과 표현력을 모두 잃게 된다.
    • 그럼에도 불구하고 로 타입이 생긴 이유는 제네릭 타입이 없을때 작성된 코드들과의 하위 호완성을 유지하기 위해서이다.

로 타입인 List와 매개변수화 타입인 List의 차이는?

  • List 는 제네릭 타입에서 완전히 발을 뺀 것이고, List<Object>는 모든 타입을 허용한다는 의사를 컴파일러에게 명확히 전달한 것이다.
  • 즉, List<String> 은 로 타입인 List의 하위 타입이지만, List<Object>의 하위 타입은 아니다.
  • 그 결과, List<Object> 같은 매개변수화 타입을 사용할때와 달리 List와 같은 로타입을 사용하면 타입 안정성을 잃게 된다.(코드 26-4 예제 참고)
1
2
3
4
5
6
7
8
9
10
11
12
// 코드 26-4 런타임에 실패한다. - unsafeAdd 메서드가 로 타입(List)을 사용 (156-157쪽)
public class Raw {
    public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        unsafeAdd(strings, Integer.valueOf(42));
        String s = strings.get(0); // 컴파일러가 자동으로 형변환 코드를 넣어준다. 런타임시 형변환을 실행하려 할때 ClassCastException 이 발생한다!!!
    }

    private static void unsafeAdd(List list, Object o) {
        list.add(o);
    }
}

제네릭 타입을 쓰고 싶지만 실제 타입 매개변수가 무엇인지 신경쓰고 싶지 않다면 물음표(?)를 사용하자.

  • 예컨대 제네릭 타입인 Set<E>의 비한정적 와일드 카드 타입은 Set<?> 이다.
  • 어떤 타입이라도 담을 수 있는 가장 범용적인 매개변수화 Set 타입이다.

비한정적 와일드카드 타입인 Set<?>와 로 타입인 Set의 차이는?

  • 와일드 카드 타입은 안전하고, 로 타입은 안전하지 않다.
  • 와일드 카드 타입 Collection<?>에는 (null 외에는) 어떤 원소도 넣을 수 없다.

로 타입을 쓰지 말라는 규칙에도 소소한 예외가 몇 개 있다.

  • 첫 번째는 class 리터럴에는 로 타입을 써야한다.
    • 자바 명세는 class 리터럴에 매개변수화 타입을 사용하지 못하게 했다.(배열과 기본 타입은 허용한다.)
    • 예를 들어, List.class, String[].class, int.class는 허용하고 List<String>.class, List<?>.class는 허용하지 않는다.
  • 두 번째는 런타임에는 제네릭 타입 정보가 지워지므로 instanceof 연산자는 비한정적 와일드카드 타입 이외의 매개변수화 타입에는 적용할 수 없다.

핵심 정리: 로 타입을 사욯아면 런타임에 예외가 일어날 수 있으니 사용해선 안된다. 로 타입은 제네릭이 도입되기 이전 코드와의 호환성을 위해 제공될 뿐이다. Set<Object>는 어떤 타입의 객체도 저장할 수 있는 매개변수화 타입이고, Set<?>는 모종의 타입 객체만 저장할 수 있는 와일드카드 타입이다. 그리고 이들의 로타입인 Set은 제네릭 타입 시스템에 속하지 않는다. Set<Object>Set<?>는 안전하지만, 로타입인 Set은 안전하지 않다.

출처 및 참고

This post is licensed under CC BY 4.0 by the author.

[이펙티브자바] 아이템25-톱레벨 클래스는 한 파일에 하나만 담으라

[이펙티브자바] 아이템27-비검사 경고를 제거하라