본문 바로가기
Java/Effective Java

[아이템 26] 로 타입(raw type)은 사용하지 말라

by setung 2022. 2. 7.

아이템 26부터 제네릭에 대한 내용이다.

로 타입이란 타입 매개변수가 없는 제네릭 타입으로 List를 예로 들 수 있다.

 

List rawList = new ArrayList();                 // 로 타입 리스트
List<String> strings = new ArrayList<>();       // 문자열을 담는 리스트
List<Integer> integers = new ArrayList<>();     // 정수를 담는 리스트

rawList.add(1);
rawList.add(1.1);
rawList.add("raw");
rawList.add('r');

strings.add(1);  	// 컴파일 에러

 

로 타입은 Object를 넣을 수 있어 어떤 객체도 담을 수 있다. 그래서 문제가 되는데 예상치 못하게 넣지 말아야 할 객체를 넣었다면 형 변환 런타임 오류가 발생할 수 있다.

 

▶ List vs List<Object>

둘 다 Object를 담는 리스트로 어떤 타입이든 담을 수 있는 리스트지만 엄연히 서로 다른 리스트이다.

List는 어떤 타입을 담을지 명시를 안 한 것이고, List<Object>는 모든 타입을 허용한다는 의미이다.

 

또한 List<String>은 List의 하위 타입이지만, List<Object>의 하위 타입은 아니다.

    public static void main(String[] args) {
        List list = new ArrayList();                    // 로 타입 리스트
        List<String> strings = new ArrayList<>();       // 문자열을 담는 리스트
        List<Integer> integers = new ArrayList<>();     // 정수를 담는 리스트

        funRawList(list);
        funRawList(strings);
        funRawList(integers);

        funObjectList(list);
        funObjectList(strings);         // 컴파일 에러
        funObjectList(integers);        // 컴파일 에러

        funWildCard(list);
        funWildCard(strings);
        funWildCard(integers);
    }

    static void funRawList(List list) {

    }

    static void funObjectList(List<Object> list) {

    }


    static void funWildCard(List<?> list) {

    }

로 타입 매개변수 자리에는 어떤 List라도 들어갈 수 있으나, List<Object> 자리에는 List나 List<Obejct> 타입만 가능하다. 

참고로 매개변수 제네릭 타입이 명확하진 않을 땐 와일드카드 <?>를 사용하면 된다

 

로 타입을 사용하는 예

  • class 리터럴
    • ex) List.class (O)
    • ex) List<String>.class (X)
  • instanceof 연산자
    • list instanceof List (O)
    • list instanceof List<String> (X)

 

결국 로 타입을 쓰지 말아야 하는 이유는 안전성 이유인데 자바에서 허용하는 이유는 과거 코드의 호환성이다. 

 

댓글