2016-03-15 2 views
7

Sto eseguendo il porting del codice Java7 su Java8 e ho trovato il seguente problema. Nella mia base di codice ho due metodi:La chiamata Java 8 al metodo generico è ambigua

public static <T> ImmutableSet<T> append(Set<T> set, T elem) { 
    return ImmutableSet.<T>builder().addAll(set).add(elem).build(); 
} 

public static <T> ImmutableSet<T> append(Set<T> set, Set<T> elemSet) { 
    ImmutableSet.Builder<T> newSet = ImmutableSet.builder(); 
    return newSet.addAll(set).addAll(elemSet).build(); 

compilatore restituisce l'errore su Match ambiguo per il metodo aggiungono delle nel seguente test:

@Test(expected = NullPointerException.class) 
public void shouldAppendThrowNullPointerForNullSecondSet() { 
    ImmutableSet<Integer> obj = null; 
    CollectionUtils.append(ImmutableSet.of(1), obj); 
} 

Errore del compilatore:

reference to append is ambiguous both method append(java.util.Set,T) in CollectionUtils and method append(java.util.Set,java.util.Set) in CollectionUtils match

Come fare per riscrivere queste funzioni per lavorare con l'inferenza di tipo dall'introduzione con Java8?

+1

È possibile farlo funzionare con 'ImmutableSet obj = null; \t \t ImmutableSet set = ImmutableSet.of (1); \t append (set, obj); '. – Tunaki

+0

Impossibile riprodurre in ideone (utilizzando HashSet anziché ImmutableSet, ma ciò non dovrebbe importare da una prospettiva di inferenza di tipo) http://ideone.com/oT6SbF. –

+0

@AndyTurner Non riesce a compilare con jdk 1.8.0_51 (ed Eclipse Mars.2). – Tunaki

risposta

7

Hai trovato i nuovi miglioramenti di inferenza di tipo generalizzato di destinazione in Java 8. Sono presenti alcune domande di overflow dello stack. Such as this one.

Java 8 può inferire il tipo di restituzione di un generico in base al metodo passato come argomento. Pertanto, quando si chiama CollectionUtils.append(ImmutableSet.of(1), obj), Java 8 sta tentando di restituire un set immutabile dalla chiamata statica of che corrisponde a uno dei metodi append. In questo caso, potrebbe pensare di restituire uno ImmutableSet<Object> anziché lo ImmutableSet<Integer> che stai chiaramente cercando di restituire. E poi non è chiaro se chiami append(Set<Object>, Object) o append(Set<Integer>, Set<Integer>).

La soluzione più semplice è rinominare il secondo metodo appendAll. Oppure, si potrebbe seguire la correzione suggerita here e cambiare la chiamata a qualcosa di simile:

CollectionUtils.append(ImmutableSet.<ImmutableSet<Integer>>of(1), obj); 

mi piacerebbe restare con rinominando il secondo metodo me stesso però. Salverà gli altri sviluppatori dello stesso dolore quando provano a usare la libreria.