Podczas aktualizacji aplikacji do Java 8 natknąłem się na dziwny problem z numerem Google Guava newArrayList
w kilku miejscach.Java 8 Compiler Confusion Z przeciążonymi metodami
Spójrz na ten przykład:
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);
}
}
w pierwszym przykładzie, kiedy dostanę UnmodifiableIterator
najpierw do własnej zmiennej, a następnie zadzwonić newArrayList
dostanę to, czego oczekuję, czyli wartości Iteratory kopiowane do nowy List
.
W drugim przykładzie, gdzie forEnumeration
idzie bezpośrednio do metody newArrayList
, otrzymuję z powrotem List
z zawierającym iterator (który zawiera wartość).
Według IntelliJ nim myśli że oba połączenia metody należy do newArrayList(Iterator<? extends E> elements)
ale znalazłem podczas debugowania, że druga rozmowa faktycznie idzie do newArrayList(E... elements)
.
Dzieje się tak tylko wtedy, gdy kompiluję się z Oracle JDK8 ukierunkowanym na Java8. Jeśli celuję na 7, działa dobrze.
Jest to duży kod z wieloma autorami. Nie mogę więc odpowiedzieć, dlaczego jeden sposób został wybrany na inny. Po prostu muszę je wszystkie znaleźć. Dzięki za podpowiedź na temat łatania guawy. Nie myślałem o tym. Chyba wiem, co robię dziś rano. – ryber
Jedyny problem z usunięciem newArrayList (E ...) polega na tym, że gdy kompilator zacznie używać właściwego. Wygląda na to, że jedyną bezpieczną rzeczą jest szybkie sprawdzenie ich wszystkich. – ryber
To dziwne, ponieważ powodem, dla którego nie należy używać właściwego, jest to, że kompilator uważa, że właściwy nie ma zastosowania i że nie powinien nagle zmienić się, gdy niewłaściwy został usunięty. Kiedy próbowałem sztuczek z Netbeanami, działało to zgodnie z oczekiwaniami, ale może być inaczej w przypadku IntelliJ, które, jak powiedziałeś, wybrałoby właściwy cel wywołania. Ale pomyślałem, że jeśli IntelliJ i leżący u podstaw javac nie zgadzają się, IntelliJ nie ukryje błędów javac. Czy rzeczywiście generuje pliki klas? – Holger