java wildcard

참고 문서

개요

작년에 wildcard에 대해 스터디한 내용이 있었다는 사실에  한 번 개깜놀

까맣게 잊고 있었다는 사실에 두 번 개깜놀

wildcard 와 type parameter 간의 가장 중요한 차이점은 code statement 내에 선언된 param이 재참조되는지 여부이다.

재참조 되면 type parameter 써야 하고, 재참조 안되고 귀찮으면 그냥 ? 쓴다.

Wildcard ?

java syntax에는 ? 라는 것이 있다. generic type parameter로 쓰인다. (e.g. ArrayList<?>)

Long story short…

generic type parameter 를 명확히 결정하지 않은 채로 두기 위한(=unknown type) syntax

Generic 의 type parameter 는 polymorphism 을 지원하지 않는다.

generic에서는 type prarmeter 에 대하여 polymorphism 을 지원하지 않는다.  다음 예제를 보자.

Generic

Collection<String> foo = new ArrayList<String>;
Collection<Object> refFoo = foo; //compile error!!

refFoo.add(new Object());
String bar = foo.get(0); //만일 line2 가 error가 아니었다면, bar 에 Object 를 할당하는 참사가 발생하게 된다.

 

얼핏 생각하면 ArrayList<Dog> 을 List<Animal> 으로 받을 수 있을 것 같지만, 상기 예제와 같은 문제를 막기 위해 Generic 의 type parameter 는 문법적으로 subtype 변환을 허용하지 않는다.

혼란을 막기 위한 제한이지만, type 체크가 엄격하면 유연한 사용이 힘들다. Wildcard 는 이런 상황을 해결하기 위해 고안된 문법이다.

 

case Wildcard<?>
private void foo(Collection<?> c) {
  for (Object iter : c)
    System.out.println(iter);
}

List<String> bar = new ArrayList<String>;
bar.add("hello");

foo(bar); //okay!!

 

case Obect

private void foo(Collection<Object> c) {
  for (Object iter : c)
    System.out.println(iter);
}

List<String> bar = new ArrayList<String>;
bar.add("hello");

foo(bar); //compile error!!

 

Wildcard 사용시 주의할 점

 

bounded wildcard

 

spring에서 용례

spring-context 의 SimpleApplicationEventMulticaster.multicastEvent()

정확한 type을 알 수 없는 ApplicationListner<T>를 이터레이션 하기 위하여 wildcard가 사용되었다.

SimpleApplicationEventMulticaster.java

@Override
public void multicastEvent(final ApplicationEvent event) {
  for (final ApplicationListener<?> listener : getApplicationListeners(event)) {
    Executor executor = getTaskExecutor();
    if (executor != null) {
      executor.execute(new Runnable() {
        @Override
        public void run() {
          invokeListener(listener, event);
        }
      });
    }
    else {
      invokeListener(listener, event);
    }
  }
}

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중