2013-08-07 10 views
14

私は3つの方法があります:ジェネリック

//1 -- check one item 
public static <T> void containsAtLeast(String message, 
             T expectedItem, 
             Collection<? extends T> found) { 
    if (!found.contains(expectedItem)) 
     Assert.fail("...");   
} 

//2 -- check several items 
public static <T> void containsAtLeast(String message, 
             Collection<? extends T> expectedItems, 
             Collection<T> found) { 
    for (T exptetedItem : expectedItems) 
     containsAtLeast(message, exptetedItem, found);   
} 

//3 -- check several items, without message parameter 
public static <T> void containsAtLeast(Collection<? extends T> expectedItems, 
             Collection<? extends T> found) { 
    containsAtLeast(null, expectedItems, found); 
} 

を私は方法が//2を呼び出す//3が、それは、それは方法//1を起動していないことを期待します。私が期待していることに間違いはありますか?

*私は、SDK 1.7.0_25を使用し、4.3 *

答えて

12

あなたの第二の方法は、foundT)のジェネリック型のサブタイプであることをexpectedItems? extends T)のジェネリック型を期待Eclipseの。

3つ目の方法では、2つのジェネリックタイプ間にサブタイプの関係はありません。両方ともTに拡張されていますが、たとえば兄弟になる可能性があります。

したがって、2番目のメソッドを呼び出すことはできません。

例:あなたはこれらの型と第三の方法を呼び出す想像:

containsAtLeast(Collection<Integer> e, Collection<String> f) 

だからあなたの第三の方法でTObjectです。そして、あなたの最初のメソッドはT = Objectでも呼び出されます。

+0

さらに、「T」はこの場合はメソッドごとの型パラメータであるため、3つの宣言はすべて基本的に互いに独立しています。 –

+0

しかし、なぜ最初のメソッドが呼び出されたのですか? '\\ 1'の' T 'が '\\ 3'の' Collection 'と同じ場合、' \\ 1'の 'found'は' Collection <? 'コレクション>' '\\ 3'を拡張しますか?どこが間違っていますか? –

+2

@assylias:ありがとうございます:私はこの細部を見落としました。 - ''を '// 2 'に' found'に追加すると、期待通りに動作します – Ralph