a field in the inner class. Once the outer method has terminated and its stack frame has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory. import javax.swing.*; public class FooGUI { public static void main(String[] args) { //initialize GUI components final JFrame jf = new JFrame("Hello world!"); //allows jf to be accessed from inner class body jf.add(new JButton("Click me")); // pack and make visible on the Event-Dispatch Thread SwingUtilities.invokeLater(new Runnable() { @Override public void run() { jf.pack(); //this would be a compile-time error if jf were not final jf.setLocationRelativeTo(null); jf.setVisible(true); } }); } } Blank final The blank final, which was introduced in Java 1.1, is a final variable whose declaration lacks an initializer. Previous to Java 1.1, a final variable was required to have an initializer. A blank final, by definition of "final", can only be assigned once. i.e. it must be unassigned when an assignment occurs. In order to do this, a Java compiler runs a flow analysis to ensure that, for every assignment to a blank final variable, the variable is definitely unassigned before the assignment; otherwise a compile-time error occurs. final boolean hasTwoDigits; if (number >= 10 && number < 100) { hasTwoDigits = true; } if (number > -100 && number <= -10) { hasTwoDigits = true; // compile-error because the final variable might already be assigned. } In addition, a blank final also has to be definitely assigned before being accessed. final boolean isEven; if (number % 2 == 0) { isEven = true; } System.out.println(isEven); // compile-error because the variable was not assigned in the else-case. Note though that a non-final local variable also needs to be definitely assigned before being accessed. boolean isEven; // *not* final if (number % 2 == 0) { isEven = true; } System.out.println(isEven); // Same compile-error because the non-final variable was not assigned in the else-case. C/C++ analog of final variables In C and C++, the analogous construct is the const keyword. This differs substantially from final in Java, most basically in being a type qualifier: const is part of the type, not only part of the identifier (variable). This also means that the constancy of a value can be changed by casting (explicit type conversion), in this case known as "const casting". Nonetheless, casting away constness and then modifying the object results in undefined behavior