2017-10-08 14 views
1

findメソッドの呼び出し時にエラーが報告されました。Javaからジェネリックスを継承する際の問題

interface Node<N extends Node<N>> { 
    void setNext(N next); 
    N getNext(); 
} 

interface Entry<K, V> extends Node<Entry<K, V>> { 
    K getKey(); 
    void setValue(V value); 
    V getValue(); 
} 

class Test { 
    public static <N extends Node<N>> N find(N base, Object obj) { 
     for (N node = base; node != null; node = node.getNext()) 
      if (node.equals(obj)) 
       return node; 
     return null; 
    } 

    public static <K, V, E extends Entry<K, V>> E getEntry(E[] table, K key) { 
     return find(table[0], key); 
    } 
} 

バインドされた不一致:テストタイプの一般的なメソッドfind(N、Object)は引数(E、K)には適用されません。推定されるタイプEは、有界パラメータの有効な代替ではありません>

これはなぜそうであるか分かりません。

答えて

4

問題はここにある:

interface Node<N extends Node<N>> { 
    void setNext(N next); 
    N getNext(); 
} 
interface Entry<K, V> extends Node<Entry<K, V>> { 
    K getKey(); 
    void setValue(V value); 
    V getValue(); 
} 

あなたはE extends Entry<E, V>を持っています。 E.getNext()は何を返しますか? Entry<K, V> extends Node<Entry<K, V>>以降、E.getNext()、少なくともは返信Entry<K, V>となります。

しかし、それはEでしょうか? Entry<K, V>.getNext()は、Entry<K, V>のインスタンスを返すことが保証されています。実際にはEntry<K, V>と同じ型を返すことは保証されていません。コードにはE.getNext()Eのインスタンス割り当て互換性をEntry<K, V>に返すように強制するものは何もありません。

したがって、お使いのfindの方法で推測できるものはEntry<K, V>ですが、これは必ずしもEと互換性がありません。

2

は、私たちは一緒に

E extends Entry<K, V> 

Entry<K, V> extends Node<Entry<K, V>> 

これら二つのことを知っているfind方法ためにはしかし

E extends Node<Entry<K, V>> 

は、私たちが必要とする適用することを意味

E extends Node<E> 

EはサブタイプがEntry<K, V>であり、それに等しいとは言えません。

Nodeには、具体的な実装タイプ(N)を表す型パラメータがありますが、Entryはありません。この目的のために第3の型のパラメータを追加することで修正できます。

interface Entry<K, V, E extends Entry<K, V, E>> extends Node<E> { 
    K getKey(); 
    void setValue(V value); 
    V getValue(); 
} 

public static <K, V, E extends Entry<K, V, E>> E getEntry(E[] table, K key) { 
    return find(table[0], key); 
}