Exceptions are used during resolution for control flow. The code should be refactored to make the control flow more explicit
method resolution errors and inference errors trigger exceptions which
are then handled to update the overload resolution state. The use of
exceptions is a pragmatic choice, as many times we need to skip many
elements on the stack trace, and go back to Resolve.selectBest - and it
is also kind of handy when we need to check nested expression (e.g.
lambda return type) in method context: triggering an exception here will
end up doing the right thing. Exceptions are also caught and nested -
meaning we can easily form nested diagnostics.
That said, some recent (and not so recent) performance benchmarks
pointed out that extensive use of exception is essentially at odds with
the G1 collector. It is very possible that a significant performance
speedup could be achieved by dropping exceptions. Another element in
favor of dropping exceptions is that it would make the flow a little bit
easier to follow when e.g. debugging and or troubleshooting issues.
method resolution errors and inference errors trigger exceptions which
are then handled to update the overload resolution state. The use of
exceptions is a pragmatic choice, as many times we need to skip many
elements on the stack trace, and go back to Resolve.selectBest - and it
is also kind of handy when we need to check nested expression (e.g.
lambda return type) in method context: triggering an exception here will
end up doing the right thing. Exceptions are also caught and nested -
meaning we can easily form nested diagnostics.
That said, some recent (and not so recent) performance benchmarks
pointed out that extensive use of exception is essentially at odds with
the G1 collector. It is very possible that a significant performance
speedup could be achieved by dropping exceptions. Another element in
favor of dropping exceptions is that it would make the flow a little bit
easier to follow when e.g. debugging and or troubleshooting issues.