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.
Table of Contents
Uses of Java final keyword
We can use the java final keyword in the below cases:
- Variable
- Method
- Class
- Parameter
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.