Encontré un problema extraño usando Optionalsy 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, Barlos 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.ofse 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 cualquierBarfuente
Debería decirle a Opcional que desea una barra para esa interfaz.
fuente
javaccompila mucho más rápido, así que ...Caso
compiles1Tu
Optionaltiene el tipo genéricoBar, porque la variablebartiene tipoBar.La clase de tipo anónimo
Foo$1que crea tieneBarun supertipo, por lo tanto, el método se compila.Caso
doesNotCompileAquí,
Optionaltiene el tipo genéricoFoo$1y está intentando pasar un objeto de tipoFoo$2alorElseque no tieneFoo$1como supertipo. De ahí el error de compilación.Caso
doesNotCompile2Similar a
doesNotCompile,Optionaltiene el tipo genéricoFoo$1y está intentando pasarbar, una variable de tipoBaren laorElseque nuevamente no tieneFoo$1como supertipo.Evitando estos errores
Agregue un testigo tipo a su llamada de
Optional::of. Esto le daOptionalel tipo genéricoBar:fuente