Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional.orElse does not compile with anonymous types

I encountered a weird problem using Optionals and anonymous classes:

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() {
        });
    }
}

The first two methods do not compile with the error

java: incompatible types: <anonymous test.Foo.Bar> cannot be converted to <anonymous test.Foo.Bar>

I'd expected that, since both implement the interface Bar all three approaches work. I also cannot figure out why the third option fixes the problem. Can anyone explain this please?

like image 242
Mirco Avatar asked Dec 03 '19 13:12

Mirco


2 Answers

You can supplement the type on the first two using a type witness:

Optional.<Bar>of(new Bar(){}).orElse(new Bar(){});

This allows the compiler to see that you are expecting a return of Optional<Bar>, which #orElse can then inferr to accepting any Bar

like image 76
Rogue Avatar answered Sep 19 '22 23:09

Rogue


You'd need to tell the Optional that you want a Bar for that interface.

Bar bar = new Bar();
Optional<Bar> o = Optional.of(new Bar() {}).orElse(bar);
like image 34
Nicktar Avatar answered Sep 21 '22 23:09

Nicktar