The Java final keyword

The Java final keyword is very loosely used to indicate that something "cannot change". Specifically— and perhaps confusingly from a language design point of view— it has a number of uses:

A common misconception about the Java final keyword is that it is essentially a performance optimisation. In Java, final is much more about program design than performance, as we illustrate later when we look at some timings relating to the performance of final as a class modifier.

Using final to indicate that a class or method cannot be overridden

You can use final to specify that a whole class may not be extended, or similarly that a method cannot be overridden.

So when would you use final in this way? A common case is where:

As an example, imagine if we were implementing a template for a swing component which would have a number of subclasses, but whose subclasses would always need to draw content on the "left" and "right" side of the component, at specific coordinates. We would probably therefore implement our template component as a subclass of JComponent, requiring a public paintComponent() method:

public abstract class LeftAndRightComponent extends JComponent {
  ...

  public void paintComponent(Graphics g) {
    // calculate x and y for left side
    ...
    paintLeftSide(x, y);
    // calculate x and y for right side
    ...
    paintRightSide(x, y);
  }

  protected abstract void paintLeftSide(int x, int y);

  protected abstract void paintRightSide(int x, int y);

}

But now we have the problem that overriding classes, as well as implementing paintLeftSide() and paintRightSide(), could "accidentally" override paintComponent() itself, in effect removing the whole functionality of the class! The solution is to declare this method final:

public abstract class LeftAndRightComponent extends JComponent {
  ...
  public final void paintComponent(Graphics g) {
    ...
    paintLeftSide(x, y);
    ...
    paintRightSide(x, y);
  }
  ...
}

Now, a subclass can still override paintLeftSide() and paintRightSide(), but not paintComponent, which is declared final.

Final classes

Cases for making an entire class final are less common, but would essentially be where allowing a subclass with differing implementation could lad to unexpected behaviour. A notable example from the JDK itself is the String class. A central design decision of Java strings is that they are immutable, and some of the inner workings of strings are tightly coupled with internals of the JVM itself. These factors together mean that allowing subclasses of String could lead to some unexpected behaviour, and so the String class is defined as being final:

public final class String {
  ...
}