Java final Keyword


JavaViews 2271

Java final keyword is a non-access modifier that provides few restrictions or limitations to the user. In other words, when we use the keyword final, we cannot reassign or reinitialize them. This means we cannot change the values. In this tutorial, we will learn how to use the final keyword in various contexts.

Uses of Java final keyword

We can use the java final keyword in the below cases:

  • Variable
  • Method
  • Class
  • Parameter

Java final keyword

Java final variable

When we use the final keyword before a variable in java, we call it a final variable. Once we assign a value to a final variable, we cannot change the value or reassign new values. Generally, we use java final variables as constants. Its a best practice to name the final variables in capital letters always.

Let’s see an example below. We know that value of pi is always constant and does not have any other value. In this case, we can declare the PI variable as final.

public class Circle {

  final double PI = 3.14;
  
  public void area(int r) {
    double area = PI*r*r;
    System.out.println("Area of circle: " + area);
  }
  public static void main(String[] args) {
    Circle c = new Circle();
    c.area(4);

  }

}
Area of circle: 50.24

In case we try to modify the PI value, it will throw compilation error.

public class Circle {

  final double PI= 3.14;
  
  public void area(int r) {
    PI= 2.14;
    double area = PI*r*r;
    System.out.println("Area of circle: " + area);
  }
  public static void main(String[] args) {
    Circle c = new Circle();
    c.area(4);

  }

}
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
  The final field Circle.PI cannot be assigned

  at Circle.area(Circle.java:6)
  at Circle.main(Circle.java:12)

Blank final variable

When we do not assign any value to the final variable during declaration, we call it a blank final variable in java. If we do not initialize the final variable during declaration, then we can do the same only in a constructor, else we will get a compilation error. We cannot initialize the final variable inside any other method.

public class Circle {

  final double PI;
  
       //Initialize final variable in the constructor
  Circle() {
    PI= 3.14;
  }
  
  public void area(int r) {
    double area = PI*r*r;
    System.out.println("Area of circle: " + area);
  }
  public static void main(String[] args) {
    Circle c = new Circle();
    c.area(4);

  }

}
Area of circle: 50.24

Now, why do we need to have a blank final variable in java? The answer is when we need to have different values for the final variable each time we initialize, then we can use the blank final variable. For example, when we create an Employee class, each employee has a different employee id. Hence we cannot initialize the final variable during declaration. Each time we create an employee object, we can pass the value of empid which gets initialized in the constructor.

public class Employee {
  final int empid;
  String empname;
  
  Employee(int id) {
    empid = id;
  }
  
  public void setName(String name) {
    this.empname = name; 
  }
  public static void main(String[] args) {
    Employee e = new Employee(4321);
    Employee e1 = new Employee(1121);
    e.setName("Ravi");
    e1.setName("Kiran");
    System.out.println("Employee ID: " + e.empid);
    System.out.println("Employee name: " + e.empname);
    System.out.println("Employee ID: " + e1.empid);
    System.out.println("Employee name: " + e1.empname);
  }

}
Employee ID: 4321
Employee name: Ravi
Employee ID: 1121
Employee name: Kiran

Static final variable

We can declare a final variable as static as well in java. In this case, we can initialize the static final variable only in static block, if we do not initialize during declaration. We cannot initialize in the constructor also since it is a static final variable. Else, it will throw a compilation error.

public class StaticFinalExample {
  static final int VALUE;
  
  static {
    VALUE = 100;
  }
  
  public void display() {
    System.out.println("Value is : " + VALUE);
  }

  public static void main(String[] args) {
    StaticFinalExample s = new StaticFinalExample();
    s.display();

  }

}
Value is : 100

Java final method

When we use the java final keyword before the method, we call it a final method. In this case, we cannot override the final method. To understand this, you need to have knowledge of Inheritance in Java and Polymorphism in Java. When we have the same method in both parent and child class, we call it a method overriding.

We can call the final method directly from a subclass, but we cannot override it since it will result in a compilation error.

In the below example, we get a compilation error, when we try to override a final method in the child class

class Vehicle {
  final void speed() {
    System.out.println("Default speed");
  }
}
public class Car extends Vehicle{

  void speed() {
    System.out.println("Car speed");
  }
  public static void main(String[] args) {

  }

}
Error: LinkageError occurred while loading main class Car
  java.lang.VerifyError: class Car overrides final method Vehicle.speed()V

We can, however, call the final method of the parent class directly as below.

class Vehicle {
  final void speed() {
    System.out.println("Default speed");
  }
}
public class Car extends Vehicle{

  public static void main(String[] args) {
    Car c = new Car();
    c.speed();

  }

}
Default speed

Java final class

When we use the final keyword while creating a class in java, we call it a final class. We cannot extend a final class and does not support inheritance. Most of the java core libraries have a final class like String class for example.

final class Vehicle {
  public void speed() {
    System.out.println("Default speed");
  }
}
public class Car extends Vehicle{

  public static void main(String[] args) {
    
  }

}
The type Car cannot subclass the final class Vehicle

We can, however, use the methods of the final class, but we cannot extend it. The main purpose of final class is that we cannot inherit the features of this final class. When we do not want any class to inherit a class, in that case, we can declare it as a final class.

final public class Vehicle {
  public void speed() {
    System.out.println("Default speed");
  }
  
  public static void main(String[] args) {
    Vehicle v = new Vehicle();
    v.speed();
  }
}

Default speed

Java final parameter

We can also use the java final keyword as a parameter. In this case, we cannot change the value of the final variable passed as a parameter. We can just access the variable directly.

public class Vehicle {
  public void speed(final int sp) {
    System.out.println("Default speed is " + sp);
  }
  
  public static void main(String[] args) {
    Vehicle v = new Vehicle();
    v.speed(20);
  }
}

Default speed is 20

If we try to change the value, we will get a compilation error as below.

public class Vehicle {
  public void speed(final int sp) {
    sp = 5;
    System.out.println("Default speed is " + sp);
  }
  
  public static void main(String[] args) {
    Vehicle v = new Vehicle();
    v.speed(20);
  }
}

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
  The final local variable sp cannot be assigned. It must be blank and not using a compound assignment

  at Vehicle.speed(Vehicle.java:3)
  at Vehicle.main(Vehicle.java:9)

Java final reference variable

We can also use final keyword along with the reference variable in java. When doing so, we cannot create another instance for the same reference variable

For example, in the below code, we have declared the reference variable v as final. In this case, when we try to re-assign another reference variable to this, we will get a compilation error.

public class Vehicle {
  public void speed(int sp) {
    System.out.println("Default speed is " + sp);
  }
  
  public static void main(String[] args) {
    final Vehicle v = new Vehicle();
    v.speed(20);
    Vehicle v2 = new Vehicle();
    v = v2;
  }
}

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
  The final local variable v cannot be assigned. It must be blank and not using a compound assignment

  at Vehicle.main(Vehicle.java:10)

However, we can access the methods using this reference variable.

public class Vehicle {
  public void speed(int sp) {
    System.out.println("Default speed is " + sp);
  }
  
  public static void main(String[] args) {
    final Vehicle v = new Vehicle();
    v.speed(20);
    
  }
}

Default speed is 20

Features of Java final Keyword

  • We must initialize final variables during declaration, else we can initialize only in the constructor.
  • Java does not support the final keyword for constructors.
  • Final variable values cannot be changed.
  • We cannot inherit from a final class.
  • Java does not allow to override a final method
  • It is a best practice to name the final variables in CAPITAL letters.
  • By default all variables inside an interface are final.

Reference

Translate »