Note: I found multiple questions pointing out differences between javac
and the Eclipse compiler, but as far as I could see all of them discuss other issues.
Suppose we have this method:
public static <T, U> void foo(Supplier<T> a, Function<T, U> b, Consumer<U> c)
{
c.accept(b.apply(a.get()));
}
I found different behavior between javac
and the Eclipse Java compiler when compiling calls to this method and I'm not sure which of the two is right.
A simple use of this method could be:
// variant 1
foo(
() -> Optional.of("foo"),
value -> value.get(),
value -> System.out.println(value));
The compiler should be able to bind T
to Optional<String>
using the first argument and U
to String
using the second. So this call should be valid (in my opinion).
This compiles fine using javac
but fails to compile using Eclipse:
Type mismatch: cannot convert from void to <unknown>
Adding a type argument to the first argument (() -> Optional.<String> of("foo")
) makes it compile in Eclipse too.
Question: From a specification point of view, is Eclipse correct in rejecting this call (and why (not))?
Now suppose we want to throw a custom (runtime) exception, if the Optional
is empty:
// variant 2
foo(
() -> Optional.of("foo"),
value -> value.orElseThrow(() -> new RuntimeException()),
value -> System.out.println(value));
This is rejected by both, javac
and the Eclipse compiler, but with different error messages:
javac
: "unreported exception X; must be caught or declared to be thrown"- Eclipse compiler: "Type mismatch: cannot convert from void to <unknown>"
When I add the type argument to the first argument as above, Eclipse succeeds in compiling while javac
still fails. When I add <RuntimeException>
as type argument to the second argument, it's the other way around, Eclipse fails and javac
succeeds.
Question: Again, are the compilers right in rejecting this call and why?
In my opinion both variants should compile fine without additional hints by using type arguments. If so I'll fill one bug report for javac
(regarding the "unreported exception") and one for the Eclipse compiler (regarding the "type mismatch"). But first I want to be sure the specification shares my point of view.
Versions used:
javac
: 1.8.0_66- Eclipse JDT: 3.11.1.v20151118-1100
EDIT:
I filled bug 482781 for the issue in Eclipse.
The issue with javac
is already reported as JDK-8056983, see Tunakis answer.