2014-05-09 1 views
-2

제네릭, 와일드 카드 및 상속에 대해 조금 읽었습니다. 그러나 여전히 getFoo() 라인에서 에러가 발생하는 이유를 알 수 없습니다. doit (this); 누군가 이런 일이 발생하는 이유를 설명해 주실 수 있습니까? 그리고이를 수행하는 적절한 방법은 무엇입니까?java generics : 와일드 카드 및 하위 클래스 - 왜 이런 일이 발생합니까?

public class A<T> { 
    private Foo<T, ? extends A<T>> foo; 
    public Foo<T, ? extends A<T>> getFoo() { 
     return foo; 
    } 
    public void setFoo(Foo<T, ? extends A<T>> foo) { 
     this.foo = foo; 
    } 
} 

public class B extends A<Integer>{ 
    public B() { 
     setFoo(new Bar()); 
     getFoo().doit(this); 
    } 
} 

public class Bar implements Foo<Integer, B> { 
@Override 
    public void doit(B a) { 
     System.out.println("some process"); 
    } 

} 

public interface Foo<T, V extends A<T>> { 
    public void doit(V a); 
} 
+3

질문에 컴파일러 오류가 있습니다. –

답변

0

당신은 메서드 호출에 와일드 카드 extends 인수 (귀하의 경우 getFoo().doit(<? extends A<Integer> a))로 null이 아닌 값을 제공 할 수 없습니다. 그 이유는 컴파일러가 원래의 일반적인 정의가 무엇인지 알 수 없기 때문에 코드를 컴파일하는 것을 거부하기 때문입니다.

귀하의 문제는 simle List<?>로 설명 될 수있다 :

위의 코드는 (떨어져 컴파일 오류 :에서) 완전히 잘 보이지만이 상상

public static List<Integer> myList = new ArrayList<Integer>(); 

public static List<? extends Number> getList() { 
    return myList; 
} 

public static void main() { 
    getList().add(Integer.valueOf(1000)); // Can not substitute wildcard by Integer 
} 
:

public static void main() { 
    getList().add(Long.valueOf(1000)); // This would definitely cause ClassCastException later when someone calls myList.get(0) 
} 

UPDATE 와일드 카드를 제거하는 데 필요한 문제를 해결하려면 (예 : 다른 유형 매개 변수를 클래스에 추가하는 방법) 정의 :

public class A<T, V extends A<T, V>> { 
    private Foo<T, V> foo; 
    public Foo<T, V> getFoo() { 
     return foo; 
    } 
    public void setFoo(Foo<T, V> foo) { 
     this.foo = foo; 
    } 
} 

public class B extends A<Integer, B>{ 
    public B() { 
     setFoo(new Bar()); 
     getFoo().doit(this); 
    } 
} 
+0

안녕하세요 파벨, 메서드 인수로 서브 클래스 인스턴스를 수락하는 적절한 방법을 제안 해 주시겠습니까? –

+0

@ParagParalikar done. –

+1

"인자로 와일드 카드가있는 메소드를 호출 할 수 없습니다"할 수 있습니다. 인수로'null'을 전달하면됩니다. 그리고 그것은 단지'extends' 와일드 카드를위한 것입니다. 'super' 와일드 카드의 경우, 바인딩의 인스턴스 인 것을 전달할 수 있습니다. – newacct

관련 문제