Ich stieß auf einige, zumindest für mich, seltsames Verhalten in Eclipse 4.4 und Java 8 Build 45 beim Ausführen eines Extrakt-Ausdruck Refactoring. Das folgende Beispiel zeigt das Original und fehlerfreien Code vor dem Extrakt Refactoring Anwendung:Typ Mismatch nach dem Extrahieren von Ausdruck mit generischen Rückgabetyp
import java.util.Map;
import java.util.Set;
public class MyMap<K, V> {
public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
for (Map.Entry<? extends K, ? extends V> entry : mapToCopy.entrySet()) {
}
}
}
Das Ergebnis der Eclipse Refactoring sieht wie folgt aus und führt zu der Fehlermeldung unten, dass bezieht sich auf den Lesezugriff von entrySet
in der loop Deklaration:
public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
Set<?> entrySet = mapToCopy.entrySet();
for (Map.Entry<? extends K, ? extends V> entry : entrySet) {
^^^^^^^^
}
}
Type mismatch: cannot convert
from element type capture#3-of ?
to Map.Entry<? extends K,? extends V>
verändert I die Art der Erklärung der entrySet
zu Set<Map.Entry<? extends K, ? extends V>>
. Dieses Mal wird der Fehler bei der Initialisierung der Erklärung angegeben, nämlich:
public void putAll(final Map<? extends K, ? extends V> mapToCopy) {
Set<Map.Entry<? extends K, ? extends V>> entrySet = mapToCopy.entrySet();
^^^^^^^^^^^^^^^^^^^^
for (Map.Entry<? extends K, ? extends V> entry : entrySet) {
}
}
Type mismatch: cannot convert
from Set<Map.Entry<capture#1-of ? extends K,capture#2-of ? extends V>>
to Set<Map.Entry<? extends K,? extends V>>
Da der ursprüngliche Code nicht kompiliert, ich bin ein wenig verwirrt. Vielleicht kann mir jemand helfen und eine Erklärung geben? Danke im Voraus!
Beachten Sie, dass 'Set erweitert Map.Entry erweitert K,? erweitert V >> entrySet = mapToCopy.entrySet(); 'wird funktionieren. [JLS § 14.4.2] (http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14.2) spricht über die Übersetzung von 'Iterable' in das Enhanced 'für' Aussage. Siehe auch [diese Antwort] (http://stackoverflow.com/a/16753901/5065475) –
@AndyBrown: Können Sie bitte auf "Beachten Sie, dass [...] funktioniert", bitte. Was muss ich ändern, damit es funktioniert? – Marcus
In Java8, versuchen Sie auch 'map.forEach ((Schlüssel, Wert) -> {...})'. Schlüssel/Wert werden als ein unbekannter Subtyp von K/V auf geeignete Typen zurückgeführt. Die API ist auch flexibel genug, wenn wir die Typen diktieren - 'map.forEach ((K-Taste, V-Wert) -> {...})' – ZhongYu