2016-07-08 2 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「すべてが一致しますか?スーパー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

'extend'が異なります。それは容易です。それを 'super'に変更して何が起こるかを見てください。 –

+0

はい。 superと同じエラー – Gangadhar

2

フォームA<? extends B>のジェネリック型は?BまたはBの任意のスーパータイプで置き換えることができることを意味しています。したがって、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

'<?リストを拡張する<? Q1 >> 'を拡張しますか? '' Collection'のサブクラスを 'f'に渡したい場合、どうすればいいですか? –