Encontrei um problema estranho usando Optional
classes anônimas e s:
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() {
});
}
}
Os dois primeiros métodos não são compilados com o erro
java: incompatible types: <anonymous test.Foo.Bar> cannot be converted to <anonymous test.Foo.Bar>
Eu esperava isso, já que ambos implementam a interface, Bar
todas as três abordagens funcionam. Também não consigo descobrir por que a terceira opção resolve o problema. Alguém pode explicar isso, por favor?
java
optional
anonymous-class
Mirco
fonte
fonte
Optional.of
é fixoOptional<Bar>
. Em todos os outros casos, éOptional<SubAnonymousSubclassOfBar>
. Eu esperava que os outros dois inferissem também o limite superior comum apropriadoBar
. Mas, aparentemente,Optional<SomeSubclassOfBar>(bar).orElse(someOtherSubclassOfBar)
precisa de alguma ajuda.Respostas:
Você pode suplementar o tipo nos dois primeiros usando uma testemunha de tipo:
Isso permite que o compilador veja que você espera um retorno
Optional<Bar>
, do qual #orElse pode deduzir a aceitar qualquerBar
fonte
Você precisaria informar ao opcional que deseja uma barra para essa interface.
fonte
javac
compila muito mais rápido, então ...Caso
compiles1
Seu
Optional
tem o tipo genéricoBar
, porque a variávelbar
tem o tipoBar
.A classe anônima do tipo que
Foo$1
você cria possuiBar
um supertipo, portanto, o método é compilado.Caso
doesNotCompile
Aqui,
Optional
tem o tipo genéricoFoo$1
e você está tentando passar um objeto do tipoFoo$2
para oorElse
qual não temFoo$1
um supertipo. Daí o erro de compilação.Caso
doesNotCompile2
Semelhante a
doesNotCompile
,Optional
tem o tipo genéricoFoo$1
e você está tentando passarbar
, uma variável do tipoBar
para aorElse
qual novamente não temFoo$1
um supertipo.Evitando esses erros
Adicione uma testemunha de tipo à sua chamada de
Optional::of
. Isso forneceOptional
o tipo genéricoBar
:fonte