JDK-4447072 : RFE: Add an exception block to the try statement
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 1.3.0
  • Priority: P5
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 2001-04-18
  • Updated: 2007-12-11
  • Resolved: 2007-12-11
Related Reports
Relates :  
Relates :  
Description

Name: yyT116575			Date: 04/18/2001


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)


I think a construct such as the finally block should be added for exceptions.
The behaviour would be the same as with the finally mechanism, except that
exception blocks would be executed only when an exception is being thrown. So
they would be ignored when a method returns normally. It would look like the
following:

try
{
  ...
}

catch (...)
{
}

catch (...)
{
}

exception
{
  ...
}

finally
{
  ...
}

This would be usefull for things that must be done when something goes wrong,
no matter the cause. In the finally block it is not possible to know about
this condition.

The same can be achieved in the current situation by adding a
"catch (Throwable e)" block and re-throwing the exception at the end of it.
This, however, requires a class test for as many exception types as are
declared to be thrown by the method. Otherwise Throwable would have to be added
to the throws list. This has no meaning and would show through an
implementation issue in the interface. Furthermore, if such a method already
has several exception handlers, the additional code would have to be added to
all of them somehow. The situation can become quite complicated.

In search of a practical example one could think of a connection API
towards some resource. Say we would like to manage connection objects in some
sort of pool. The policy could then be to get rid of a specific connection
object whenever an exception occurred through one of its methods, because it
would be too difficult to determine if its state is still consistent.

Generating code for this feature is not very difficult. In the class file, the
code could be added to the exception handler with catch_type 0, which is the
finally block. It would consist of an if statement testing if an exception is
being thrown and having the contents of the exception block as its body. To make
this work, a generated try statement would have to be put around the original
finally block code. The generated try statement would have itself a finally
block containing the forementioned if statement. In this way both the exception
and the finally block are always executed, which is necessary because they are
not related logically.

It is important to note that this feature would not break existing code. It
doesn't even require a modification of existing VMs. This is a rather simple
compiler issue.

A more detailed description about this RFE:

The semantics of a try statement with a finally block but no exception block
are unchanged. They are as described in section 14.18.2 of the Java Language
Specification.

A try statement with an exception block is executed by first executing the try
block. Then there is a choice:

- If execution of the try block completes normally, then the exception block is
  ignored.
- If execution of the try block completes abruptly because of a throw of a
  value V, then there is a choice:
  - If the run-time type of V is assignable to the parameter of any catch
    clause of the try statement, then the first (leftmost) such catch clause is
    selected. The value V is assigned to the parameter of the selected catch
    clause, and the Block of that catch clause is executed. Then there is a
    choice:
    - If the catch block completes normally, then the exception block is
      executed. Then there is a choice:
      - If the exception block completes normally, then the try statement
        completes normally.
      - If the exception block completes abruptly for any reason, then the try
        statement completes abruptly for the same reason.
    - If the catch block completes abruptly for reason R, then the exception
      block is executed. Then there is a choice:
      - If the exception block completes normally, then the try statement
        completes abruptly for reason R.
      - If the exception block completes abruptly for reason S, then the try
        statement completes abruptly for reason S (and reason R is discarded).
  - If the run-time type of V is not assignable to the parameter of any catch
    clause of the try statement, then the exception block is executed. Then
    there is a choice:
    - If the exception block completes normally, then the try statement
      completes abruptly because of a throw of the value V.
    - If the exception block completes abruptly for reason S, then the try
      statement completes abruptly for reason S (and the throw of value V is
      discarded and forgotten).
  - If execution of the try block completes abruptly for any other reason R,
    then the exception block is executed. Then there is a choice:
    - If the exception block completes normally, then the try statement
      completes abruptly for reason R.
    - If the exception block completes abruptly for reason S, then the try
      statement completes abruptly for reason S (and reason R is discarded).

When a try statement has both an exception and a finally block, then the
following holds:

- When the individual rules for exception and finally blocks result in both
  blocks needing to be executed, then the exception block is executed first.
  Then there is a choice:
  - If the exception block completes normally, then the finally block is
    executed. Then there is a choice:
    - If the finally block completes normally, then the try statement
      completes normally.
    - If the finally block completes abruptly for any reason, then the try
      statement completes abruptly for the same reason.
  - If the exception block completes abruptly for reason R, then the finally
    block is executed. Then there is a choice:
    - If the finally block completes normally, then the try statement
      completes abruptly for reason R.
    - If the finally block completes abruptly for reason S, then the try
      statement completes abruptly for reason S (and reason R is discarded).
(Review ID: 120914) 
======================================================================

Comments
EVALUATION Essentially, if try{} throws an exception, then exception{} is always executed; it's a last chance to clean up before finally{} comes into play. If finally{} isn't present, then exception{} is just a more specialized form of finally{}, which is not a worthwhile language addition. If finally{} is present, it can generally clean things up just as well as exception{}. (I accept that finally{} might benefit from more info about a thrown exception - see 5108147.) Even if exception{} was more functional, it complicates control flow in exception handling where Java has done well by keeping the flow simple.
11-12-2007

EVALUATION I am unable to guess what exactly is desired here. Complicating try-finally any further seems like a really bad idea, but I'll give the submitter the benefit of the doubt and ask for a coherent proposal that states the desired semantics precisely. In the meantime I'm marking this incomplete. gilad.bracha@eng 2001-04-18 Ok, now I have a concrete proposal. In my judgement, it has a very poor power to weight ratio. The circumstances where this is needed are rare, and do not justify the complexity. gilad.bracha@eng 2001-05-23
23-05-2001