Hello,

On 18/04/2022 5:43 am, some-java-user-99206970363698485...@vodafonemail.de wrote:

Hello,

are there any plans to improve exception handling in combination with `finally` 
blocks?

I'm not aware of anything, nor what that anything could realistically be. You make only one suggestion that has a little merit.

Currently, when a `finally` block does not complete normally, the original 
exception is
silently discarded (as described in the JLS). This behavior is error-prone, not 
obvious
at all, and has been criticized in the past a lot. An example for this is 
https://stackoverflow.com/q/48088
and the linked posts there.

The behaviour of try/catch/finally is not "obvious at all", you have to read what it means and when you do that you clearly see what happens regarding exceptions.

While javac warns you about this issue when using `-Xlint:finally`, it is only 
a warning
and not even enabled by default.

Are there any plans to forbid usage of `break`, `continue`, `yield` and 
`return` in
`finally` blocks?

Why would we do that? What would that gain?

Switch expressions have already set a precedent for this by not allowing to 
leave the
switch expression by something other than a `throw` or `yield` statement, 
trying to use
for example a `return` statement causes a compilation error.

That is because it is an _expression_ - expressions have to have different language rules to statements. There is no connection to a finally block.

Similarly for `throw` and any implicitly thrown exceptions, is there a plan to 
at least
add the original exception as suppressed one to the newly thrown?

That suggestion is not completely without merit, but nor is it a "slam-dunk" obvious thing to do. The semantic implications of the exceptions matter, and semantics come from the programmers intent. There's no reasonable way to automagically determine that when an exception is created that another exception (that led to the finally block) should be inserted as a "suppressed exception". That would actually be completely wrong to do in many circumstances you would instead need to act when the exception would terminate the finally block and then add the original exception as the "suppressed" exception. But really the programmer is in the best position to decide how exceptions need to be handled.

Of course one could argue that the same applies to `catch` clauses whose body 
accidentally
causes an exception which discards the caught one. However the main difference 
is that

Yes exactly the same.

there, only a specific exception type is caught (and discarded), whereas for 
`finally`
exceptions of _any_ type are discarded. It could also be argued that adding 
suppressed

We have multi-catch now so that argument is somewhat weaker.

exceptions decreases performance or causes memory leaks, but one the other hand
this behavior was explicitly included try-with-resources statements, most 
likely because the
value this adds was considered more important than any performance issues this
might cause.

try-with-resources added support for suppressed exceptions because the automatic closing of the resource could throw an exception, and that had to be factored in to the whole mechanism.

Also, it is important to keep in mind that this affects _all_ Throwable types, 
including
VM errors which you really should not catch, and which due to a `finally` block 
might
silently be discarded. Most, if not all, code in which a `finally` does not 
complete
normally does not seem to consider this.

That is true. But for me a finally block is intended to be quite small and succint and should be written from the perspective of "an unexpected exception has occurred, what it is it critical for me to do before leaving the current scope".

This is also not a theoretical problem; this issue exists in multiple open 
source projects,
potentially even in the JDK itself.
Often the code can be rewritten by either moving the complete code or parts of 
it
outside of the `finally` block, or by introducing a local variable to hold the 
result and
to return that after the `finally` block.

What do you think about this topic?

I think there is no clear and obvious solution that the language can put in place here.

Just my personal 2c.

Cheers,
David

Is backward compatibility a concern? If so, can you provide an example where 
using such
a pattern provides any notable advantages which justify the potential loss of 
thrown
VM errors or exceptions.

Kind regards



Reply via email to