Dev/Java

<Object>와 <? extends Object>의 차이

NillK 2019. 6. 26. 21:37

분명히 알았는데, 다시 되짚어 보려니 뭔가 모호해서 generics를 정리해보기로 했다. 글로 하나씩 정리해보는 거랑 그냥 알고 있다고 생각하는 거랑 생각보다 큰 차이라는 걸 요즘 들어 느낀다. 오늘은 <Object><? extends Object>의 차이.

이 둘은 얼핏 보기엔 같아 보이지만 조금 다르다. 저 키워드를 기반으로 찾으면 또 나오는 비슷한 질문이<?>와<? extends Object>의 차이인데 이 두 경우는 같으며 <? extends Object>는 몇 케이스를 제외하고는extends Object가 redundant하다고 하다고 한다.

그렇다면List와List<? extends Object>는?

두 코드를 풀어 말하자면 List<Object>는 이 list가 가지고 있는 객체들이 Object 라는 것을 얘기하는 거지만, List<? extends Object>는 이 list가 가지고 있는 객체들이 Object의 subclass임을 말한다. 다시 말해, List<? extends Object>List<String>, List<Number>, List<SomeClass>등의 List를 뜻한다. 그래서 List<Number>List<? extends Object>의 서브타입일 수 있지만, List<Object>의 서브타입일 수는 없다. 여기서 혼동이 올 수 있는데, NumberObject의 subclass지만 List<Number>List<Object>의 subclass일 수 없다.

그래서 아래 두 단락의 코드 중 위 코드는 되지만, 아래 코드는 컴파일 에러다.

public void listTest(List<Object> list) {
  list.add("Hello, generics!");
  list.add(1);
}
public void listTest(List<? extends Object> list) {
  list.add("Hello, generics!"); // compile error
}

위에 썼듯이 List<? extends Object>라는 건 Object의 서브 클래스를 가지고 있는 리스트이다. 컴파일러는 이 리스트가 가지고 있는 게 Object일지, Number일지, String인지 그 외 다른 Class일지 모른다. 다만 Object를 상속한 어떤 객체들을 담고 있는 List라는 것만 알 수 있다. 따라서 저기서 그냥 String을 넣으려고 하면 에러가 나는 것이다. 넘어 온 List는 List<Number>일 수도 있고, List<Foo>일 수도 있다. 그리고 컴파일러는 그 사실을 모르기 때문에 에러를 일으킨다. String을 넣으려고 했는데, 넘어 온 List가 사실은 Number를 가지고 있는 List이면 어떡해!

'Dev > Java' 카테고리의 다른 글

[Java] Upper bounded wildcards  (0) 2016.12.28