Java: final keyword

In this article, we will discuss final keyword in Java. final keyword falls under non-access modifier category

final keyword can be used with

  • Variable
  • Method
  • Class

We will discuss each one in detail

 

1) final variable

A variable declared with final modifier is known as final variable in Java. The value of final variable cannot be changed once it is initialized. These final variables are CONSTANT in Java

Note: As a programming practice in Java, final variable declared in upper case (CAPS)

Let us see an example on final variable

Employee.java

1_final_keyword_error_changing_value

Compile-time error: The final field <final_variable> cannot be assigned

Explanation:

The value of final variable can be initialized at three places (considering it’s an instance data member)

  • Initialize where it is declared
  • Inside instance block i.e.; {curly braces}
  • Constructor

Note: final variable checks whether value is initialized in above order and if it doesn’t find value is initialized then compiler throws error

 

Let us see what happens, if final variable is not initialized at any of these 3 places?

Employee.java

2_final_keyword_error_not_initializing_final_variable

Compile-time error: The blank final field <final_variable> may not have been initialized

Explanation:

  • As we stated above, final field or variable declared expects the value to be initialized at these 3 places and in the listed order
  • If it doesn’t find in any of these places, then compiler throws error at constructor as it is last point where it expects the value to be initialized

 

Blank final field or variable

Final variable declared without initializing value is known as blank final field or blank final variable

It is must to initialize final field or final variable. Otherwise, compiler throws error stating reason,

The blank final field <final_variable> may not have been initialized

Employee.java

package in.bench.resources.finalkeyword.example;

public class Employee {

	// CHECK 1: instance data member with final modifier
	final int EMPLOYEE_ID;

	// instance initializer block
	{
		// CHECK 2: jumps here, if final variable NOT initialized
	}

	// CHECK 3: default no-arg constructor
	Employee() {
		EMPLOYEE_ID = 1001;
	}

	// main() method - the entry point to JVM to begin execution
	public static void main(String[] args) {
		Employee employee1 = new Employee();
		System.out.println("Employee ID : " + employee1.EMPLOYEE_ID);
	}
}

Output:

Employee ID : 1001

 

In above example blank final field or variable,

  • Being an instance data member, the value of final field or final variable doesn’t changes for every new object
  • Reason: final field cannot re-assigned once it is initialized
  • It look like employee id going to remain same for every new instance created

 

So, what is the real use of blank final field or variable in OOPS concept?

Example: Upon joining a new organization, every employee is assigned with new & unique employee Id for identification and other purposes. So, employee Id must be assigned with unique number and it shouldn’t change over the course of its tenure with organization

For this purpose, blank final field or variable are very useful

Let us see an example based on blank final field or blank final variable

Employee.java

package in.bench.resources.finalkeyword.example;

public class Employee {

	// CHECK 1: instance data member with final modifier
	final int EMPLOYEE_ID;

	// instance initializer block
	{
		// CHECK 2: jumps here, if final variable NOT initialized
	}

	// CHECK 3: default no-arg constructor
	Employee(int empid) {
		EMPLOYEE_ID = empid;
	}

	// main() method - the entry point to JVM to begin execution
	public static void main(String[] args) {
		Employee employee2 = new Employee(1002);
		System.out.println("Employee ID : " + employee2.EMPLOYEE_ID);
	}
}

Output:

Employee ID : 1002

 

Explanation:

In above Employee class,

  • EMPLOYEE_ID is neither initialized directly while declaring nor initilized at 2nd place i.e.; instance block
  • Instead at 1-arg constructor, we are taking one integer parameter and this parameter value get assigned to final field EMPLOYEE_ID
  • This way, we have the flexibility of assigning new and unique EMPLOYEE_ID while creating new objects for employee joining organization
  • But once initialized for every new employee, it doesn’t get changed

 

Static blank final variable

Adding static modifier to final variable is known as static final variable

Static final variable declared without initializing value is known as static blank final field or static blank final variable

It belongs to class and it’s going to remain same for every employees (CONSTANT)

Let us an example on static final variable

Employee.java

package in.bench.resources.finalkeyword.example;

public class Employee {

	// CHECK 1: static data member with final modifier
	final static String ORGANIZATION_NAME;

	// static block
	static {
		// CHECK 2: jumps here, if final static variable NOT initialized
		ORGANIZATION_NAME = "ABC Pvt. Ltd.";
	}

	// main() method - the entry point to JVM to begin execution
	public static void main(String[] args) {
		System.out.println("Organization Name : " + Employee.ORGANIZATION_NAME);
	}
}

Output:

Organization Name : ABC Pvt. Ltd.

 

Explanation:

The value of final static variable can be initialized at two places (considering it’s a static data member)

  • Initialize where it is declared
  • Inside static block i.e.; static {curly braces}

Note: final static variable checks whether value is initialized in above order and if it doesn’t find value is initialized then compiler throws error

Compile-time error: The blank final field <final-static-field> may not have been initialized

 

final parameter

If we declare any input parameters as final, then it cannot be changed

Let us see an example on final parameter

TestFinalParameter.java

3_final_keyword_error_re_initializing_final_local_variable

Throws compilation error with message “The final local variable count cannot be assigned. It must be blank and not using a compound assignment

 

2) final method

A final method cannot be overridden but class containing final methods can be inherited and can call final method from sub class

Let us see an examples on final methods

 

What happens, when we override final method in sub class?

ParentClass.java

4_final_keyword_error_final_method_cannot_be_overridden

ChildClass.java

5_final_keyword_error_final_method_cannot_be_overridden_b

Throws compilation error with message “Cannot override the final method from ParentClass

 

Whether final method can be invoked from inherited sub class?

Yes absolutely, we can very well invoke final method from inherited sub class

ParentClass.java

package in.bench.resources.finalkeyword.example;

public class ParentClass {

	// instance method with final modifier
	final void displayFinalMessage() {
		System.out.println("ParentClass : This is final method and cannot be overridden");
	}
}

ChildClass.java

package in.bench.resources.finalkeyword.example;

public class ChildClass extends ParentClass {

	// final method cannot be override

	// main() method - the entry point to JVM to begin execution
	public static void main(String[] args) {

		ChildClass child = new ChildClass();
		child.displayFinalMessage(); // invoking final method from sub class
	}
}

Output:

ParentClass : This is final method and cannot be overridden

 

Thus, it is clear from above example that final methods can be invoked from sub class but cannot be overridden while inheriting

 

3) final class

A final class cannot be inherited i.e.; final class cannot be sub-classed

ParentClass.java

6_final_keyword_error_final_class_cannot_be_inherited

ChildClass.java

7_final_keyword_error_final_class_cannot_be_inherited_b

Throws compilation error stating reason “The type ChildClass cannot subclass the final class ParentClass

 

Point to remember about final keyword:

  • final modifier can be applied to variables, methods or classes
  • A final variables cannot be changed, once it is initialized
  • A final variable declared without initialized is known as blank final variable
  • A static final variable declared without initialized is known as static blank final variable
  • A final methods cannot be overridden although final method can be invoked
  • A final class cannot be inherited
  • final input parameters cannot be changed (method input parameters)
  • Local final variables must be initialized before use in the method body
  • Constructor cannot be final
  • All final variables declared in upper case as a convention and it is considered as good practice
  • Variables declared inside Interface are implicitly final and it must be initialized where its declared
  • final and finally are 2 different keywords where finally used in exception handling in Java
  • Similarly, final and finalize are 2 different keywords where finalize is invoked before garbage collection in Java
  • By marking or declaring variables, methods or classes as final improves the performances as it get bind during compile time

That’s all about final keyword in Java

 

References:

https://docs.oracle.com/javase/tutorial/java/IandI/final.html

 

Read Also:

Happy Coding !!
Happy Learning !!