2017-07-27 65 views
2

我得到類型不匹配的錯誤,直到我重構代碼,以這樣的:泛型是不變的,但這種編譯沒有錯誤

public final Stream<Map.Entry<E, Integer>> orderedStreamOfEntries() { 
     return this.m_map.entrySet() 
       .stream() 
       .sorted(Comparator.comparingInt(Entry::getValue)) 
       .map(AbstractMap.SimpleImmutableEntry::new);    
    } 
  • 返回類型Stream<Entry<E, Integer>>
  • 在該類型的流這個程序的結束是Stream<SimpleImmutableEntry<E, Integer>>

形式類型參數E有這樣的定義:

<E extends Enum<E> & MyCustomInterface> 

我不明白爲什麼這似乎是可以接受的編譯器。由於Java泛型是不變的,即使java.util.AbstractMap.SimpleImmutableEntry實現了​​,我也會說Stream<SimpleImmutableEntry<>>不是返回類型的子類型Stream<Entry<>>

+0

從類定義中定義的'E'是什麼? – ArtB

+0

@ArtB:我已將定義編輯到問題 – scottb

+0

如果有疑問在調試時,我建議將流上的每個操作作爲對特定變量的賦值進行拆分。使用具有重構支持的IDE使得這個微不足道。這會讓你看到類型的演變。 – ArtB

回答

2

你犯了兩個錯誤。第一個假設SimpleImmutableEntry::newFunction<Entry, SimpleImmutableEntry> *,實際上它可以解釋爲Function<Entry, Entry>,其中恰好會返回 a SimpleImmutableEntry

其次,看該簽名map()

<R> Stream<R> map(Function<? super T, ? extends R> mapper) 

通過返回? extends R,該方法也可以自由解釋R作爲超的lambda表達式返回類型,這意味着即使是Function<Entry, SimpleImmutableEntry>可能導致Stream<Entry>,或甚至Stream<Object>

實際的解釋取決於推斷的返回類型,在你的情況下是Stream<Entry>

*爲簡潔起見,使用原始條目類型。

+0

<<<首先假設SimpleImmutableEntry :: new是一個函數 *,實際上它可以解釋爲函數,它恰好返回SimpleImmutableEntry。>>> 看起來好像成爲關鍵, – ArtB

+0

@scottb是的,這是一回事。重點是'Function '可以(讀取:必須)返回'Entry'的子類。 – shmosel

+0

是的,我明白你在說什麼。令我困惑的是,我的IDE將'map()'函數的返回類型顯示爲Stream >'。如果這確實是返回類型,那麼似乎應該有一個錯誤。 – scottb