제네릭이 좋긴 하지만 불편한점이 몇몇 있습니다. 바로 제네릭간에 상속이라는 개념이 적용이 안된다는거죠.
이전에도 잠깐 설명했지만
List<Object> 와 List<String> 는 절대로 상속관계가 아닙니다. 따라서 서로 호환이 안된다 라는거죠.
하지만 String 도 Object의 하위클레스이니 List<String>을 List<Object> 에다가 집어 넣을수 있어야 할거 같습니다.
그러면 어떻게 하느냐? List<String>에 있는걸 하나씩 꺼내서 List<Object>에다가 집어넣는겁니다.
자 그럼 이걸 사용자가 하지말고 List 에다가 addAll이라는 메소드를 만들어 봅시다.
전달받는 그럼 전달받는 인자는 List<Object>에다가 집어넣을 테니 List<Object> 라는게 되어야 할텐데 List<String>을 List<Object>로 바꿀 방법이 없습니다.
이럴때 이용하는것이 와일드 카드 라는놈입니다.
addAll(List<Object> list) 가 아닌 addAll(List<? extends Object> list) 라고 써주면 됩니다.
이라는 의미입니다. - 실제로는 <? extends E> 라고 적혀있겠죠
addAll(List<? extends Object> list ) 가되면 일단 제네릭 형식의 List이고 들어있는 자료의 형은 정확히 모르겠지만 어쨌든 Object 상속한것. 그러니까 저기있는거 하나씩 꺼내다가 List<Object>에다가 집어넣어도 아무런 문제가 없다는겁니다.
그렇다면 반대로 List<String>의 입장에서 List<Object>에다가 넣고싶다.
이런 메소드는 Stack에 있는 popAll 이라는 메소드가 있지만 쉽게 예를 들기 위해서 List로 하겠습니다.
List<String>의 popAll 이라는 메소드는 String 을 담을수 있는 어떤 리스트를 전달 받아서 거기다가 자신이 가지고 있는 자료를 전부 넣고 싶다(addAll).
이럴때도 일단 popAll(List<String> list) 라면 당연히 실행할수 있습니다. 그런데 String 이 아닌 Object 리스트도 가능합니다. 이럴때 사용하는것이 super 키워드입니다. 다들 알겠지만 extends는 하위클레스를 의미하고 super은 상위클레스를 의미할때 씁니다.
그러면 extends와 비슷하게 <? super String> 라고 써줄수 있습니다.
뭔진 잘모르겠는데 어쨋든 String의 상위클레스 라는거죠
이후로 여러가지 내용이 써져있는데 super과 extends 를 상황에 맞게 햇갈리지 말고 쓰세여 라는 말입니다.
'Effective Java > Chapter 5' 카테고리의 다른 글
항목 29. 타입 안전이 보장되는 혼성(heterogeneous) 컨테이너의 사용을 고려하자. (0) | 2012.01.30 |
---|---|
항목 27. 제네릭 메소드를 애용하자. (0) | 2012.01.26 |
항목 26. 제네릭 타입을 애용하자. (0) | 2012.01.25 |
항목 25. 배열보다는 List를 사용하자. (0) | 2012.01.18 |
항목 24. 컴파일 경고 메시지가 없게 하자. (0) | 2012.01.12 |