개발

[제네릭] 컬렉션이나 단일 원소 컨테이너에서 매개변수화 되는 대상은 무엇일까?

오렌지색 귤 2022. 2. 20. 23:52
반응형

이펙티브 자바 "아이템 33 - 타입 안전 이종 컨테이너를 고려하라"를 읽는 도중, 한 구문이 이해가 되지 않았습니다.

 

다음은 이펙티브 자바 198쪽에 나오는 문단입니다.

 

 

제네릭은 Set<E>, Map<K, V> 등의 컬렉션과 ThreadLocal<T>, AtomicReference<T> 등의 단일원소 컨테이너에도 흔히 쓰인다.

이런 모든 쓰임에서 매개변수화되는 대상은 (원소가 아닌) 컨테이너 자신이다.

따라서 하나의 컨테이너에서 매개변수화할 수 있는 타입의 수가 제한된다.

컨테이너의 일반적인 용도에 맞게 설계된 것이니 문제될 건 없다.

예컨대 Set에는 원소의 타입을 뜻하는 단 하나의 타입 매개변수만 있으면 되며, Map에는 키와 값의 타입을 뜻하는 2개만 필요한 식이다.

 

 

저는 2번째 줄인 "이런 모든 쓰임에서 매개변수화되는 대상은 (원소가 아닌) 컨테이너 자신이다." 라는 문장에 대해 이해가 되지 않았습니다.

 

 

 

 


무슨 뜻일까?

 

사실 Set<Integer> 라는 자료구조를 떠올렸을 때, 흔히 Set에는 Integer 객체 또는 Integer 클래스의 하위 타입인 객체만 들어갈 수 있다고 생각합니다.

 

들어가는 원소의 관점에서 String 이라던가 Double 등의 타입을 지닌 객체는 들어갈 수 없다라고 생각을 합니다.

 

그래서 저도 이 문장 자체를 한동안 이해하지 못했습니다.

 

스터디원분과의 토론 끝에 난 결론은 제네릭을 통해 제한되는 것은 들어가는 원소가 아니라 Set이라는 컨테이너 관점에서 봐야 한다는 것입니다.

 

Set<Integer>는 Integer 하위 타입만을 받을 수 있고, Set<String>은 String의 하위 타입만을 받을 수 있습니다.

 

결국 제네릭에 의해서는 컬렉션이나 단일원소 컨테이너가 제한되는 것이며, 로 타입에서는 모든 객체를 받을 수 있었지만, 제네릭으로 타입을 선언한 이후에는 그 자신이 제한된다는 의미로 해석했습니다.

 


스터디원의 재미난 비유

 

한 스터디원께서 재미난 비유를 들어 이 문장에 대한 해석을 해주셨습니다.

 

모양과 크기가 똑같은, 서로 구분되지 않는 두 개의 그릇이 있다고 가정하겠습니다.

 

사용자는 한 그릇에는 쓰레기를 버리기로 했고, 다른 그릇에는 음식을 넣어두기로 했습니다.

 

사용자 입장에서는 쓰레기를 담은 그릇에 음식을 넣으면 안되고, 음식을 넣어든 그릇에 쓰레기를 버리면 안됩니다.

 

하지만 엄밀하게 따졌을 때, 과연 해당 음식이 절대 쓰레기를 담은 그릇에 들어가면 안되는 음식일까요?

 

반대로 해당 쓰레기가 절대로 음식을 담은 그릇에 들어가면 안되는 쓰레기일까요?

 

 

 

아니라고 생각합니다.

 

사실 제네릭을 통해서는 그릇 자체에 음식이나 쓰레기를 담을 수 밖에 없다는 제한이 생기게 되는 것입니다.

 


 

반응형