Why does Optional.map make this assignment work?

Carl Minden :
Optional<ArrayList<String>> option = Optional.of(new ArrayList<>());

Optional<ArrayList<?>> doesntWork = option;

Optional<ArrayList<?>> works = option.map(list -> list);

The first attempted assignment does not compile, but the second one with the map does. It feels like the map shouldn't actually accomplish anything, but for some reason it turns my Optional<ArrayList<String>> into an Optional<ArrayList<?>>. Is there some sort of implicit cast going on?

Eran :

If you look into the code of map and follow all the method calls, you'll see that option.map(list -> list) ends up returning new Optional<>(option.get()). So you can replace your last assignment with:

Optional<ArrayList<?>> works = new Optional<>(option.get());

This creates a new Optional<ArrayList<?>> and initializes its value instance variable (whose type is ArrayList<?>) with the ArrayList<String> returned by map.get(). This is a valid assignment.

Is there some sort of implicit cast going on?

No, map returns a new Optional instance. It doesn't cast the original instance on which it was called.

Here's the chain of method calls:

option.map(list -> list)

returns (since option is not empty)

Optional.ofNullable(mapper.apply(value))

which in your case is the same as

Optional.ofNullable(value)

which returns (since the value is not null):

Optional.of(value)

which returns

new Optional<>(value)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=35295&siteId=1