Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Try-finally clauses defined and demonstrated

Through code samples, tables, and a Java virtual machine simulation, this article examines the bytecodes of the Java virtual machine that deal with finally clauses

  • Print
  • Feedback

Page 3 of 4

Exception table:
   from    to   target type
     0     18     18   any


The bytecodes of the finally clause begin by popping the return address off the stack and storing it into local variable two. At the end of the finally clause, the ret instruction takes its return address from the proper place, local variable two.

HopAround: A Java virtual machine simulation

The applet below demonstrates a Java virtual machine executing a sequence of bytecodes. The bytecode sequence in the simulation was generated by the javac compiler for the hopAround() method of the class shown below:

class Clown {
    static int hopAround() {
        int i = 0;
        while (true) {
            try {
                try {
                    i = 1;
                }
                finally {    // the first finally clause
                    i = 2;
                }
                i = 3;
                return i;    // this never completes, because of the continue
            }
            finally {        // the second finally clause
                if (i == 3) {
                    continue; // this continue overrides the return statement
                }
            }
        }
    }
}


The bytecodes generated by javac for the hopAround() method are shown below:

   0 iconst_0             // Push constant 0
   1 istore_0             // Pop into local var 0: int i = 0;
                          // Both try blocks start here (see exception table, below).
   2 iconst_1             // Push constant 1
   3 istore_0             // Pop into local var 0: i = 1;
   4 jsr 16               // Jump to mini-subroutine at offset 16 (the first finally clause) 
   7 goto 22              // Jump to offset 22 (to just below first finally clause)
                          // Catch clause for the first finally clause:
  10 astore_3             // Pop the reference to thrown exception, store in local variable 3
  11 jsr 16               // Jump to mini-subroutine at offset 16 (the first finally clause)
  14 aload_3              // Push the reference (to thrown exception) from local variable 3
  15 athrow               // Rethrow the same exception
                          // The first finally clause:
  16 astore 4             // Store the return address in local variable 4
  18 iconst_2             // Push constant 2
  19 istore_0             // Pop into local var 0: i = 2;
  20 ret 4                // Jump to return address stored in local variable 4
                          // Bytecodes for the code just after the first finally clause:
  22 iconst_3             // Push constant 3
  23 istore_0             // Pop into local var 0: int i = 3;
                          // Bytecodes for the return statment:
  24 iload_0              // Push the int from local variable 0 (i, which is 3)
  25 istore_3             // Pop and store the int into local variable 3 (the return value, i)
  26 jsr 37               // Jump to mini-subroutine at offset 37 (the second finally clause)
  29 iload_3              // Push the int from local variable 3 (the return value)
  30 ireturn              // Return the int on the top of the stack
                          // Catch clause for the second finally clause:
  31 astore_1             // Pop the reference to thrown exception, store in local variable 1
  32 jsr 37               // Jump to mini-subroutine at offset 37 (the second finally clause)
  35 aload_1              // Push the reference (to thrown exception) from local variable 1
  36 athrow               // Rethrow the same exception
                          // The second finally clause:
  37 astore_2             // Store the return address in local variable 2
  38 iload_0              // Push the int from local variable 0 (i)
  39 iconst_3             // Push constant 3
  40 if_icmpne 46         // If the top two ints on the stack are unequal, jump to offset 46: if (i == 3) {
  43 goto 2               // Jump to offset 2 (the top of the while block): continue;
  46 ret 2                // Jump to return address stored in local variable 2
Exception table:
   from   to  target type
     2     4    10   any
     2    31    31   any


The hopAround() method returns from the first finally clause by executing past the closing curly brace, but returns from the second finally clause by executing a continue statement. The first finally clause, therefore, exits via its ret instruction. But because the second finally clause exits via a continue, its ret instruction is never executed. The continue statement causes the JVM to jump to the top of the while loop again. This results in an endless loop, even though it is a return statement that originally causes the second finally clause to be executed in the first place. The continue statement in the finally clause supersedes the return statement, so the method never returns.

  • Print
  • Feedback

Resources
  • The book The Java Virtual Machine Specification (http://www.aw.com/cp/lindholm-yellin.html), by Tim Lindholm and Frank Yellin (ISBN 0-201-63452-X), part of The Java Series (http://www.aw.com/cp/javaseries.html), from Addison-Wesley, is the definitive Java virtual machine reference.
  • Previous Under The Hood articles
  • The lean, mean virtual machine -- Gives an introduction to the Java virtual machine. Look here to see how the garbage collected heap fits in with the other parts of the Java virtual machine.
  • The Java class file lifestyle -- Gives an overview to the Java class file, the file format into which all Java programs are compiled.
  • Java's garbage-collected heap -- Gives an overview of garbage collection in general and the garbage-collected heap of the Java virtual machine in particular.
  • Bytecode basics -- Introduces the bytecodes of the Java virtual machine, and discusses primitive types, conversion operations, and stack operations in particular.
  • Floating Point Arithmetic -- Describes the Java virtual machine's floating-point support and the bytecodes that perform floating-point operations.
  • Logic and Arithmetic -- Describes the Java virtual machine's support for logical and integer arithmetic, and the related bytecodes.
  • Objects and Arrays -- Describes how the Java virtual machine deals with objects and arrays, and discusses the relevant bytecodes.
  • Exceptions -- Describes how the Java virtual machine deals with exceptions, and discusses the relevant bytecodes.