Durante l'aggiornamento di un'app in Java 8 mi sono imbattuto in un problema strano con google guava newArrayList
in un paio di punti.Confusione del compilatore Java 8 Con metodi sovraccaricati
Date un'occhiata a questo esempio:
import com.google.common.collect.UnmodifiableIterator;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.BasicAttribute;
import java.util.ArrayList;
import static com.google.common.collect.Iterators.forEnumeration;
import static com.google.common.collect.Lists.newArrayList;
public class NewArrayListIssue {
public static void main(String[] args) throws NamingException {
UnmodifiableIterator<?> elements = forEnumeration(getEnumeration().getAll());
System.out.println("declarefirst = " + newArrayList(elements)); // calls newArrayList(Iterator<? extends E> elements)
ArrayList directCopy = newArrayList(forEnumeration(getEnumeration().getAll()));
System.out.println("useDirectly = " + directCopy); //calls newArrayList(E... elements)
}
public static Attribute getEnumeration(){
return new BasicAttribute("foo",1);
}
}
Nel primo esempio quando ho la UnmodifiableIterator
prima nella propria variabile e quindi chiamare newArrayList
ottengo quello che mi aspetto, che è i valori Iteratori copiati in una nuovo List
.
Nel secondo esempio in cui il forEnumeration
va direttamente nel metodo newArrayList
torno un List
con una contenente all'iteratore (che contiene il valore).
Secondo Intellij si pensa che entrambe le chiamate di metodo dovrebbe essere quello di newArrayList(Iterator<? extends E> elements)
ma ho trovato durante il debug che la seconda chiamata viene effettivamente newArrayList(E... elements)
.
Accade solo quando compilo con Oracle JDK8 indirizzato a Java8. Se bersaglio a 7, funziona bene.
È un grande numero di codice con molti autori. Quindi non posso rispondere perché un modo è stato scelto rispetto ad un altro. Ho solo bisogno di trovarli tutti. Grazie per il suggerimento sulla patch guava. Non avevo pensato di farlo. Credo di sapere cosa sto facendo stamattina. – ryber
L'unico problema con la rimozione di newArrayList (E ...) è che una volta fatto il compilatore inizia a usare quello giusto. Quindi sembra che l'unica cosa veramente sicura sia di valutarli rapidamente tutti. – ryber
Questo è strano perché il motivo per non usare quello giusto è che il compilatore pensa che quello giusto non sia applicabile e che non dovrebbe cambiare improvvisamente quando quello sbagliato è stato rimosso. Quando ho provato il trucco con Netbeans ha funzionato come previsto, ma potrebbe essere diverso con IntelliJ che, come hai detto, avrebbe raccolto il giusto obiettivo di invocazione. Ma ho pensato che se IntelliJ e il javac sottostante non erano d'accordo, IntelliJ non avrebbe nascosto gli errori di javac. Ha effettivamente generato file di classe? – Holger