개발

[제네릭] Unbounded Wildcard Type인 컬렉션에는 왜 null 값만 들어가는가?

오렌지색 귤 2022. 2. 7. 00:06
반응형

이펙티브 자바 스터디에서 제가 발표한 아이템 26의 내용에 대해 한분께서 좋은 질문을 해주셨습니다.

 

바로 Unbounded Wildcard Type 타입을 가지는 컬렉션에는 (null 외에는) 어떤 원소도 넣을 수 없는데 이를 왜 사용해야 하는가? 라는 질문이었습니다.

 

 

raw type

 

public class Test {
    public static <E> void main(String[] args) {
        List list1 = new ArrayList<String>();
        list1.add("fdf");  // 컴파일 가능
        list1.add(3);  //  ??
        list1.add(true);  //  너넨 왜 담아지는거야?
    }
}

 

제네릭을 반드시 써야하는 이유를 알기 전에 로 타입을 쓰지 말아야 할 이유부터 알아보겠습니다.

 

절대 쓰지 말아야 할 로 타입(raw type)인 list2는 String 타입의 ArrayList를 참조하고, "fdf"라는 문자열을 담을 수 있습니다.

 

그런데 사실 문제는 문자열이 아닌 정수 3 이라던지, boolean true 값 등의 다른 타입도 담을 수 있다는 것입니다.

 

그렇기에 로 타입은 절대 쓰면 안되는 것이죠.

 

 

generic

 

알겠습니다. 로 타입은 절대 쓰면 안되죠. 제네릭을 사용해야하는 이유에 대해서도 알고 있습니다. (타입 안전성 등..)

 

근데 null 외에는 어떤 원소도 넣을 수 없는 Collection<?> 와 같은 비한정적 와일드카드 타입은 대체 왜 사용하는 걸까요?

 

public class Test {
    public static <E> void main(String[] args) {
        List<?> list2 = new ArrayList<Integer>();
        list1.add(1);  // 컴파일 에러
    }
}

 

위의 코드를 보면 Integer 타입의 ArrayList 를 참조하는 list2 는 정수 값인 1을 담지 못합니다.

 

로 타입을 사용하지 않기 위해 null 값만 넣을 수 있는 불구인 List<?> 를 사용한다?

 

null 값만 넣을 수 있으니까 타입 안전성이야 당연히 유지되는거 아니겠습니까?

 

그렇다면 저 비한정적 와일드카드 타입은 대체 어디에 쓸 수 있을까요?

 

 

활용 코드

 

public static void printList(List<?> list) {
    for (Object elem: list)
        System.out.print(elem + " ");
    System.out.println();
}

 

위의 코드에서 개발자는 어떤 타입의 객체를 가진 리스트인지는 모르겠지만, 그 내부에 있는 값들을 출력할거야 라는 생각을 가지고 만들었습니다.

 

이것이 가능한 이유는 설령 개발자는 어떤 타입의 리스트인지 모르겠지만, 그 리스트에서 꺼내진 Object가 출력될때는 하위 타입의 toString()이 호출되어 정상적으로 출력이 가능하게 됩니다.

 

다만, 개발자는 어떤 타입의 객체를 담은 리스트가 들어올지도 모르는 상황에서 특정 타입의 객체를 들어온 리스트에 넣어줄 수는 없겠죠? 그래서 null 값만 넣어줄 수 있는 것 같습니다.

 

 

PS

활용 코드 및 해결 내용은 Stackoverflow를 참고했습니다!

 

What is the purpose of List<?> if one can only insert a null value?

Based on the information provided in the link, it says that: It's important to note that List<Object> and List<?> are not the same. You can insert an Object, or any subtype of Object...

stackoverflow.com

 

반응형