2010-01-28 2 views
4

[업데이트] 실제 상황은 내 초기 질문보다 약간 복잡해 보였습니다. 이를 반영하기 위해 코드를 약간 변경했습니다. [/ UPDATE]유형이 와일드 카드 일 때 일반 매개 변수로 일반 결과를 사용하는 방법은 무엇입니까?

다음과 같은 문제가 발생했습니다. 을 감안할 때 코드 같은 :

이클립스 반면

useT(capture#478 of ?) in Inter<capture#478 of ?> cannot be applied to (java.lang.Object)

나에게주지 않는다 :

The method useT(capture#1-of ?) in the type Inter<capture#1-of ?> is not applicable for the arguments (capture#2-of ?)

은 물론, 상관없이 makeT()의 결과 유형이이다 무엇 T

interface Inter<T> { 
    T makeT(); 
    void useT(T t); 
} 

public class Foo { 
    public void bar(Qux q) { 
    Inter<?> x = getInterForQux(q); 
    x.useT(x.makeT()); 
    } 

    Inter<?> getInterForQux(Qux q) { 
    if(someTest(q)) { 
     return (Inter<Integer>) mkAnInterInt(); 
    } else { 
     return (Inter<Double>) mkAnInterDouble(); 
    } 
    } 
} 

javac의 나에게 오류를 제공 매개 변수 유형은 useT()과 동일합니다. 내가 왜 이럴 수 없어? 해결 방법이 있습니까?

답변

4

와일드 카드를 사용할 때 컴파일러는 x.makeT()의 반환 유형과 x.useT()의 매개 변수 유형이 동일하다는 것을 컴파일러에서 볼 수 없습니다. 그들은 같은 것을 보장하기 위해, 당신은 여기에 일반적인 방법을 사용한다 :

public class Foo { 
    public <T> void bar(Inter<T> x) { 
     x.useT(x.makeT()); 
    } 
} 
+0

을 원하는이 당신에게 bar에 대해 동일한 서명을 제공을, 위에서 언급 한 바와 같이. 한 가지 사실,'bar'는 실제로 인터페이스 메소드이므로, 타입 한정어를 사용할 수 없습니다. 그러나 나는 T의 "범위"를 개인적인 방법으로 밀어 냄으로써 수량 기호를위한 공간을 만들기위한 코드를 항상 리펙토링 할 수 있다고 생각합니다. –

1

Inter<?>.makeT() 아무것도 반환 할 수 있기 때문에, 논리적이며, Inter<?>.useT(..) 아무것도 소비하지만,이 anythings이 다를 수 있습니다.

즉, 그것을 해결하는 것입니다 :

public <T> void bar(Inter<T> x) { 
    x.useT(x.makeT()); 
} 
+0

전혀 논리적이지 않습니다 :'x'는 하나의 타입과 하나의 타입 변수만을 가질 수 있습니다. 그러나 당신의 제안은 정확합니다. –

+0

- 실행시 제네릭 형식이 지워집니다. – Bozho

+0

예, 분명히 컴파일러는 런타임에 사용할 수없는 것을 사용할 수 없습니다. –

0

이 캡처 도우미 사용

public void bar(Qux q) { 
    Inter<?> x = getInterForQux(q); 
    barPrivate(x); 
} 
private <T> void barPrivate(Inter<T> x) { 
    x.useT(x.makeT()); 
} 

당신이 실제 사건이 너무 사소한하지

관련 문제