Encontré un problema extraño usando Optional
sy clases anónimas:
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() {
});
}
}
Los dos primeros métodos no se compilan con el error
java: incompatible types: <anonymous test.Foo.Bar> cannot be converted to <anonymous test.Foo.Bar>
Lo esperaba, ya que ambos implementan la interfaz, Bar
los tres enfoques funcionan. Tampoco puedo entender por qué la tercera opción soluciona el problema. ¿Alguien puede explicar esto por favor?
java
optional
anonymous-class
Mirco
fuente
fuente
Optional.of
se fija el tipo deOptional<Bar>
. En todos los demás casos, lo esOptional<SubAnonymousSubclassOfBar>
. Sin embargo, también hubiera esperado que los otros dos dedujeran el límite superior común apropiadoBar
. Pero aparentementeOptional<SomeSubclassOfBar>(bar).orElse(someOtherSubclassOfBar)
necesita algo de mano.Respuestas:
Puede complementar el tipo en los dos primeros utilizando un testigo de tipo:
Esto permite que el compilador vea que está esperando un retorno de lo
Optional<Bar>
que # o Else puede inferir para aceptar cualquierBar
fuente
Debería decirle a Opcional que desea una barra para esa interfaz.
fuente
javac
compila mucho más rápido, así que ...Caso
compiles1
Tu
Optional
tiene el tipo genéricoBar
, porque la variablebar
tiene tipoBar
.La clase de tipo anónimo
Foo$1
que crea tieneBar
un supertipo, por lo tanto, el método se compila.Caso
doesNotCompile
Aquí,
Optional
tiene el tipo genéricoFoo$1
y está intentando pasar un objeto de tipoFoo$2
alorElse
que no tieneFoo$1
como supertipo. De ahí el error de compilación.Caso
doesNotCompile2
Similar a
doesNotCompile
,Optional
tiene el tipo genéricoFoo$1
y está intentando pasarbar
, una variable de tipoBar
en laorElse
que nuevamente no tieneFoo$1
como supertipo.Evitando estos errores
Agregue un testigo tipo a su llamada de
Optional::of
. Esto le daOptional
el tipo genéricoBar
:fuente