Community
Participate
Working Groups
I ran into an unexpected compile error on line 13 (orElse line) of the following example class: import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; public class Example<E> { public void mapMethod(Consumer<? super E> defaultConsumer) { Map<Object, Consumer<? super E>> map = new HashMap<>(); Consumer<? super E> consumer = map.entrySet() .stream() .filter(x -> true) .map(Map.Entry::getValue) .findAny() .orElse(defaultConsumer); // <- Error here on orElse } } The message is: The method orElse(Consumer<capture#3-of ? super E>) in the type Optional<Consumer<capture#3-of ? super E>> is not applicable for the arguments (Consumer<capture#6-of ? super E>) However, it compiles fine with javac 1.8.0_45. Also worth mentioning is that on using a similar stream composition with a List<Consumer<? super E> instead of a map, it does compile.
(In reply to Boris van Katwijk from comment #0) > The message is: > > The method orElse(Consumer<capture#3-of ? super E>) in the type > Optional<Consumer<capture#3-of ? super E>> is not applicable for the > arguments (Consumer<capture#6-of ? super E>) At a quick glance this looks like a correct message to me. Types parameterized with different captures are not compatible. > However, it compiles fine with javac 1.8.0_45. Thanks for trying. Unfortunately, javac is quite "sloppy" in handling wildcard captures (see https://bugs.openjdk.java.net/browse/JDK-8016207), so this observation alone doesn't necessarily say that it's correct to accept that program. > Also worth mentioning is that > on using a similar stream composition with a List<Consumer<? super E> > instead of a map, it does compile. That sounds interesting, can you give a full example of that variant?
> That sounds interesting, can you give a full example of that variant? import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; public class Example<E> { // List of Consumer of super of c: works! public void listMethod(Consumer<? super E> defaultConsumer) { List<Consumer<? super E>> list = new ArrayList<>(); Consumer<? super E> consumer = list.stream() .filter(x -> true) .findAny() .orElse(defaultConsumer); } } Additionally I've copied the map variant to IntelliJ where it does compile, and also with javac as mentioned before. I also wrote unit tests which suggest that it uses the generic typing in a correct way, although those tests are not covering the full range of possibilities.
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.