0
public class Test {
    public static int temp(String a, String b) {
        try {
            System.out.print("A");
            return Integer.parseInt(a)/Integer.parseInt(b);
        } catch(ArithmeticException e) {
            System.out.print("C");
            return 0;
        } finally {
            System.out.print("D");
            return -1;
        }
    }
    public static void main(String[] args) {
        try {
            System.out.print(temp("1", null));
        } catch (Exception e) {
            System.out.print("E");
        } finally {
            System.out.print("F");
        }
    }
}

The output for this program is AD-1F.

But since b is null, Integer.parseInt(b) should throw a NumberFormatException, which is propagated back, and should be caught by the catch block in the main method. The output that I traced would be AD-1EF.

If the code in main method try-block is replaced with Integer.parseInt(null), output will be EF, which means that the NumberFormatException thrown by Integer.parseInt(null) should be caught in the first case.

J. T
  • 1
  • 2
    the reason for having a `finally` is to have code always executed - having a `return` in `finally` is *dangerous* (calling for surprises) - This special case is emphasized in the Java Language Specification [14.20.2. Execution of try-finally and try-catch-finally](https://docs.oracle.com/javase/specs/jls/se20/html/jls-14.html#jls-14.20.2-100-B-B-B): "**If the finally 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).**" (`return` completes abruptly) – user16320675 Apr 21 '23 at 11:37
  • I suppose that these "edge cases" have their uses, if only to help teach us how Java works in these situations, but this type of code also gives me a "nails on a chalkboard" sensation, and I am hoping that it never sees the light of day. – Hovercraft Full Of Eels Apr 21 '23 at 11:39

1 Answers1

4

By using a finally block, the execution is not halted, but executed regardless if there was an unhandled exeption or not. From the Oracle documentation:

The finally block always executes when the try block exits.

So even though a Runtime Exception is being thrown (NumberFormatException), the finally block is executed regardless. Hence, the return value of the temp function is not an Exception, but -1.

  1. A is printed
  2. parseInt throws
  3. finally block is being executed
  4. D is printed, -1 returned
  5. -1 is printed
  6. Since no Exception is in the stack frame, F is printed

EDIT (27.04.2023):

As user16320675 pointed out, the relevant Java Language Specification section is 14.20.2:

(minimal paraphrasing) If execution of the try block completes abruptly because of a throw of a value V, and the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the finally block is executed. If the finally block completes abruptly (meaning a return/yield/break/continue/throw statement), then the throw of value V is discarded and forgotten.

Hope this helps.

Simon B
  • 92
  • 1
  • 6
  • 2
    link to the relevant Java Language Specification: [14.20.2. Execution of try-finally and try-catch-finally](https://docs.oracle.com/javase/specs/jls/se20/html/jls-14.html#jls-14.20.2-100-B-B-B): "... **(and the throw of value V is discarded and forgotten).** ..." – user16320675 Apr 21 '23 at 11:38