Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
237 views
in Technique[技术] by (71.8m points)

Why Doesn't Java 8 Type Inference Consider Exceptions Thrown by Lambdas in Overload Selection?

I have a question regarding Java 8 inference with respect to lambdas and their related exception signatures.

If I define some method foo:

public static <T> void foo(Supplier<T> supplier) {
    //some logic
    ...
}

then I get the nice and concise semantic of being able to write foo(() -> getTheT()); in most cases for a given T. However, in this example, if my getTheT operation declares that it throws Exception, my foo method which takes a Supplier no longer compiles: the Supplier method signature for get doesn't throw exceptions.

It seems like a decent way to get around this would be to overload foo to accept either option, with the overloaded definition being:

public static <T> void foo(ThrowingSupplier<T> supplier) {
   //same logic as other one
   ...
}

where ThrowingSupplier is defined as

public interface ThrowingSupplier<T> {
   public T get() throws Exception;
}

In this way, we have one Supplier type which throws exceptions and one which doesn't. The desired syntax would be something like this:

foo(() -> operationWhichDoesntThrow()); //Doesn't throw, handled by Supplier
foo(() -> operationWhichThrows()); //Does throw, handled by ThrowingSupplier

However, this causes issues due to the lambda type being ambiguous (presumably unable to resolve between Supplier and ThrowingSupplier). Doing an explicit cast a la foo((ThrowingSupplier)(() -> operationWhichThrows())); would work, but it gets rid of most of the conciseness of the desired syntax.

I guess the underlying question is: if the Java compiler is able to resolve the fact that one of my lambdas is incompatible due to it throwing an exception in the Supplier-only case, why isn't it able to use that same information to derive the type of the lambda in the secondary, type-inference case?

Any information or resources which anyone could point me to would likewise be much appreciated, as I'm just not too sure where to look for more information on the matter.

Thanks!

question from:https://stackoverflow.com/questions/32323081/why-doesnt-java-8-type-inference-consider-exceptions-thrown-by-lambdas-in-overl

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If it makes you feel any better, this topic was indeed carefully considered during the JSR-335 design process.

The question is not "why isn't it able", but "why did we choose not to." When we find multiple potentially applicable overloads, we certainly could have chosen to speculatively attribute the lambda body under each set of signatures, and prune those candidates for which the lambda body failed to type-check.

However, we concluded that doing so would likely do more harm than good; it means, for example, that small changes to the method body, under this rule, could cause some method overload selection decisions to silently change without the user intending to do so. In the end, we concluded that using the presence of errors in the method body to discard a potentially applicable candidate would cause more confusion than benefit, especially given that there is a simple and safe workaround -- provide a target-type. We felt that reliability and predictability here outweighed optimal concision.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...