2017-10-08 152 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); 
    } 
} 

綁定不匹配:類型爲Test的泛型方法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>,這是肯定的。

但它會是EEntry<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>> 

這兩件事一起意味着

E extends Node<Entry<K, V>> 

但是爲了使find方法適用,我們需要

E extends Node<E> 

但這並不跟隨,因爲E只是Entry<K, V>一個亞型,不等於它。

的問題是,雖然Node具有代表其自身的具體實施類型(N)類型參數,Entry沒有。您可以通過爲此添加第三個類型參數來修復它。

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); 
}