2016-07-08 10 views
5

내 프로젝트에서 이상한 문제가 발생했습니다. 지금은 문제를 단순화하고 내 혼란을 설명하기 위해 여기 작은 예제를 작성 :Java 제네릭 유형의 "super"키워드의 문제점

public class Question { 
    class Q1 {} 

    class Q2 extends Q1 {} 

    interface In<T> { 
     void f(T t); 
    } 

    List<Q2> list; 

    void f(In<? super List<? super Q2>> in) { 
     in.f(list); 
    } 

    static void g() { 
     Question question = new Question(); 
     In<Collection<Q1>> in1 = new In<Collection<Q1>>() { 
      @Override 
      public void f(Collection<Q1> o) {} 
     }; 
     In<List<Q2>> in2 = new In<List<Q2>>() { 
      @Override 
      public void f(List<Q2> o) {} 
     }; 
     question.f(in1); //Error! 
     question.f(in2); //Error! 
    } 
} 

내 목표는 방법은 f(In<? super List<? super Q2>>) 더 유연하게하는 것입니다. 메서드에 in1 또는 in2을 전달할 수 있습니다. 그러나 어느 쪽도 통과 될 수 없다! 뭐가 잘못 되었 니?

아마도 this answer이 약간의 의미가 있습니다. 하지만 내 질문은 다릅니다! 제네릭 유형은 In<? super List<? super Q2>>이며 제네릭 유형의 제네릭 유형입니다.

+0

@AndyTurner "모든 것이 일치합니까? super Q2"그렇다면 왜 question.f (in1)이 오류입니까? 더 이상 정리할 수 있습니까? – Jerry06

+0

@ Jerry06 질문을 잘못 해석 한 것 같습니다. 재개 됐어. –

답변

0
In<Collection<? extends Q1>> in1 = new In<Collection<? extends Q1>>() { 
      @Override 
      public void f(Collection<? extends Q1> o) {} 
     }; 
     In<List<? extends Q2>> in2 = new In<List<? extends Q2>>() { 
      @Override 
      public void f(List<? extends Q2> o) {} 
     }; 
+0

'확장'이 다릅니다. 쉽습니다. 'super'로 바꾸고 무슨 일이 일어나는 지보십시오. –

+0

예. 슈퍼와 같은 오류 – Gangadhar

2

형태 A<? extends B>의 일반 유형은 ?BB 또는 임의의 수퍼 유형으로 대체 될 수 있다는 것을 의미한다. 따라서 List<? super Q2>List<Object>, List<Q1> 또는 List<Q2>과 같은 의미입니다.

Q1Q2의 수퍼 유형이지만 List<Q1>List<Q2>의 수퍼 유형이 아닙니다. 즉, List<Object>, List<Q1>List<Q2>의 유일한 수퍼 유형은 Object입니다. 따라서 f 메소드로 전달할 수있는 유일한 방법은 In<Object>입니다.

이 문제를 해결하는 방법은 실제로 필요한 유연성이 무엇인지에 따라 달라집니다. 어떤 종류의 객체를 f에 전달하고 해당 객체로 무엇을하고 싶습니까?

+0

'>'을 확장합니까? 'Collection'의 하위 클래스를'f'에 전달하려면 어떻게해야합니까? –