'Final' Keyword in Java

‘Final’ keyword represents ‘ultimate’ and ‘unchangeable’. In this post, I will talk about four usages of the ‘final’ keyword, including modifying a class, a method, local variables (basic and reference types) and a member variable.

Use ‘final’ to modify class

// The class that is modified by 'final' keyword cannot have any derived class.
// We cannot override any class methods because there is no derived class.
public final class MyClass {
    public void method() {
        // Implementation
    }
}

public class MySubClass extends MyClass {
    // Error: Cannot inherit from final 'MyClass'
}

Use ‘final’ to modify method

// The method that is modified by 'final' keyword cannot be overridden.
// For classes and methods, the keywords 'abstract' and 'final' cannot be used at the same time.
public class Parent {
    public final void method() {
        // Implementation
    }
}

public class Child extends Parent{
    @Override
    public void method() {
        // Another Implementation
        // Error: method()' cannot override 'method()' in 'Parent'; overridden method is final
    }
}

Use ‘final’ to modify local variable (Basic Type)

public class Demo {
    public static void main(String[] args) {
        int num1 = 10;
        System.out.println(num1); // 10
        num1 = 20;
        System.out.println(num1); // 20

        // The local variable that is modified by 'final' keyword cannot be assigned by another value later.
        final int num2 = 200;
        System.out.println(num2); // 200
//        num2 = 200; Error!

        // Correct, as long as the value is assigned once.
        final int num3;
        num3 = 30;
    }
}

Use ‘final’ to modify local variable (Reference Type)

Property: For primitive data type variables, we cannot modify the value of them once we use ‘final’ keyword to modify them. However, for reference data type variables, we cannot modify the address of them when ‘final’ keyword is used to modify them, but we can change the value of them.

public class Student {
    private String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class Demo01Final {
    public static void main(String[] args) {
        Student stu1 = new Student("Jason");
        System.out.println(stu1); // Address: cn.itcast.day11.demo01.Student@36baf30c
        stu1 = new Student("Kevin");
        System.out.println(stu1); // Address: cn.itcast.day11.demo01.Student@7a81197d

        final Student stu2 = new Student("Joey");
//        stu2 = new Student("John"); // Error! We cannot change the address of reference type variable
        stu2.setName("John");
        System.out.println(stu2.getName()); // Correct, we can change the variable of the object

    }
}

Use ‘final’ to modify member variable

// The member variable that is modified by 'final' keyword cannot be changed.
// 1: Since member variables have default values, we have to assign values manually after using 'final' keyword. [Option 1]
// 2: We can also use constructors to assign values to member variables. (If we have already assigned values manually, then this approach will not work.) [Option 2]
// 3: We must make sure all constructors will assign values to all member variables that have been modified by 'final'. [Option 2]
public class Person {
    private final String name;

    public Person() {
        name = "Kevin";
    }

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}