What's the deal with finally?

Prev      Next

Answer: It's strange   Applet   Java Source   Explanation

No matter how you exit a block, finally always gets executed.

   import java.awt.*;
   import java.awt.event.*;
   import javax.swing.*;
   import java.applet.*;

   // Test of finally.  There are four ways to terminate a block:
   //   1. Normally exit
   //   2. Break out using 'break'
   //   3. Raise and catch an exception
   //   4. Raise an exception that is not caught
   // This code tests all possibilities to make sure the finally block is 
   // always executed.  Notice that the break sends control right past the
   // try-finally but finally is executed anyway.

   public class Finally extends Applet implements ActionListener {
      JButton except_caught, except_not_caught, normal, breakout;
      JTextArea out;
      int limit = 100;
      Integer a[] = new Integer[20];
      String what;
      boolean breakloop = false;

      public void init () {
         setLayout(new BorderLayout());
         JPanel p = new JPanel();
         p.setLayout(new GridLayout(10,1));
         p.add(except_caught = new JButton("ArrayIndexOutOfBoundsException"));
         p.add(except_not_caught = new JButton("NullPointerException"));
         p.add(normal = new JButton("Normal Termination"));
         p.add(breakout = new JButton("Break Out of Loop"));
         except_caught.addActionListener(this);
         except_not_caught.addActionListener(this);
         normal.addActionListener(this);
         breakout.addActionListener(this);
         add("West", p);
         add("Center", new JScrollPane(out = new JTextArea()));
         for (int i=0 ; i < 20; i++) a[i] = new Integer("1");
      }

      // This is where the finally block under test is implemented
      public void doit () {
         for (int j=0 ; j < 1 ; j++) {
	    try {
	       // ArrayIndexOutOfBoundsException raised if limit > 20
               // NullPointerException raised if a[4] == null
               // Normal termination if limit <= 20, and no a[i] == null
               // Break out of loop if 'breakloop' == true
               for (int i=0 ; i < limit ; i++) {  a[i].toString();  }
               if (breakloop) {
                  out.append("Break out of loop...\n");
                  breakloop = false;
                  break;
               }
               out.append("Normally terminated...\n");
            } catch (ArrayIndexOutOfBoundsException e) {
               out.append("ArrayIndexOutOfBoundsException caught...\n");
            } finally {
               out.append("Pressed: "+what+", but made it to finally.\n");
            }
         }
      }

      public void actionPerformed (ActionEvent evt) {
         out.append("\n");
         for (int i=0 ; i < 20; i++) a[i] = new Integer("1");
         limit = 20;

         if (evt.getSource() == normal) {
            what = "Normal";
         } else if (evt.getSource() == except_caught) {
           what="ArrayIndexOutOfBoundsException";
           limit = 100;
         } else if (evt.getSource() == except_not_caught) {
           what="NullPointerException (not caught)";
           a[4] = null;
         } else if (evt.getSource() == breakout) {
           what = "Break out of loop";
           breakloop = true;
         }
         doit();
      }
   }