Bei der Verwendung von Optional
s und anonymen Klassen ist ein seltsames Problem aufgetreten :
public class Foo {
interface Bar {
}
void doesNotCompile() {
Optional.of(new Bar() {
}).orElse(new Bar() {
});
}
void doesNotCompile2() {
final Bar bar = new Bar() {
};
Optional.of(new Bar() {
}).orElse(bar);
}
void compiles1() {
final Bar bar = new Bar() {
};
Optional.of(bar).orElse(new Bar() {
});
}
}
Die ersten beiden Methoden werden nicht mit dem Fehler kompiliert
java: incompatible types: <anonymous test.Foo.Bar> cannot be converted to <anonymous test.Foo.Bar>
Ich hatte das erwartet, da beide die Schnittstelle implementieren Bar
alle drei Ansätze funktionieren . Ich kann auch nicht herausfinden, warum die dritte Option das Problem behebt. Kann mir das bitte jemand erklären?
java
optional
anonymous-class
Mirco
quelle
quelle
Optional.of
behoben istOptional<Bar>
. In allen anderen Fällen ist esOptional<SubAnonymousSubclassOfBar>
. Ich hätte erwartet, dass die anderen beiden auch die entsprechende gemeinsame Obergrenze von ableiten würdenBar
. Benötigt aber anscheinendOptional<SomeSubclassOfBar>(bar).orElse(someOtherSubclassOfBar)
etwas Händchenhalten.Antworten:
Sie können den Typ der ersten beiden mit einem Typzeugen ergänzen:
Auf diese Weise kann der Compiler sehen, dass Sie eine Rückgabe von erwarten
Optional<Bar>
, die #orElse dann ableiten kann, um eine zu akzeptierenBar
quelle
Sie müssen dem Optional mitteilen, dass Sie eine Leiste für diese Schnittstelle wünschen.
quelle
javac
kompiliert so viel schneller, so ...Fall
compiles1
Ihr
Optional
hat den generischen TypBar
, weil die Variablebar
den Typ hatBar
.Die von
Foo$1
Ihnen erstellte anonyme Typklasse hatBar
einen Supertyp, daher wird die Methode kompiliert.Fall
doesNotCompile
Hier
Optional
hat der generische TypFoo$1
und Sie versuchen ein Objekt vom TypFoo$2
zu übergeben,orElse
das nicht hatFoo$1
als Supertyp hat. Daher der Kompilierungsfehler.Fall
doesNotCompile2
Ähnlich
doesNotCompile
,Optional
hat die allgemeine ArtFoo$1
und Sie versuchen , passierenbar
, eine Variable vom TypBar
inorElse
dem wiederum hat nichtFoo$1
als Supertyp.Vermeiden Sie diese Fehler
Fügen Sie Ihrem Anruf von einen Typzeugen hinzu
Optional::of
. Dies gibt IhnenOptional
den generischen TypBar
:quelle