Java Language final


final in Java can refer to variables, methods and classes. There are three simple rules:

  • final variable cannot be reassigned
  • final method cannot be overriden
  • final class cannot be extended


Good Programming Practice

Some developer consider it good practice to mark a variable final when you can. If you have a variable that should not be changed, you should mark it final.

An important use of final keyword if for method parameters. If you want to emphasize that a method doesn't change its input parameters, mark the properties as final.

public int sumup(final List<Integer> ints);

This emphasizes that the sumup method is not going to change the ints.

Inner class Access

If your anonymous inner class wants to access a variable, the variable should be marked final

  public IPrintName printName(){
    String name;
    return new IPrintName(){
        public void printName(){

This class doesn't compile, as the variable name, is not final.

Java SE 8

Effectively final variables are an exception. These are local variables that are written to only once and could therefore be made final. Effectively final variables can be accessed from anonymus classes too.

final static variable

Even though the code below is completely legal when final variable foo is not static, in case of static it will not compile:

class TestFinal {
    private final static List foo;

    public Test() {
        foo = new ArrayList();

The reason is, let's repeat again, final variable cannot be reassigned. Since foo is static, it is shared among all instances of class TestFinal. When a new instance of a class TestFinal is created, its constructor is invoked and therefore foo gets reassigned which compiler does not allow. A correct way to initialize variable foo in this case is either:

class TestFinal {
    private static final List foo = new ArrayList();

or by using a static initializer:

class TestFinal {
    private static final List foo;
    static {
        foo = new ArrayList();

final methods are useful when base class implements some important functionality that derived class is not supposed to change it. They are also faster than non-final methods, because there is no concept of virtual table involved.

All wrapper classes in Java are final, such as Integer, Long etc. Creators of these classes didn't want that anyone can e.g. extend Integer into his own class and change the basic behavior of Integer class. One of the requirements to make a class immutable is that subclasses may not override methods. The simplest way to do this is to declare the class as final.