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

 

1.1. 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 above listed order
  • If it doesn’t find value at any of these 3 places, then compiler throws error at constructor as it is last point where it expects the value to be initialized

 

1.2. Blank final-variable or field

  • 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

Explanation:

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

 

1.3. What is the real use of blank final field/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 parameterized 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

 

1.4. Static blank final-variable or field

  • 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, 
		// checks whether final static variable is 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 at this 2 places then compiler throws error
  • Compile-time error: The blank final field <final-static-field> may not have been initialized

 

1.5. final parameter (input parameter of method)

  • 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

Compile-time error :- 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 in the inheriting/extending class
  • but class containing final-method can be inherited and can invoke final-method from sub-class

Let us see an examples on final methods

2.1. 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

Compile-time error :- Throws compilation error with message “Cannot override the final method from ParentClass

2.2. 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) {

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

Output:

ParentClass : This is final-method and cannot be overridden

Explanation:

  • Thus, it is clear from above example that final-method 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

Compile-time error :- 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. Variable/field/member :

  • A final-variable cannot be changed, once it is initialized
  • A final-variable declared without initializing value is known as blank final-variable
  • A static final-variable declared without initialized is known as static blank final-variable
  • 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

B. Method/behavior :

  • A final-method cannot be overridden although final method can be invoked from inherited sub-class

C. Class :

  • A final-class cannot be inherited

D. Parameter/Method-parameter :

  • final input parameters cannot be changed (method input parameters)
  • Local final variables must be initialized before use within method-body

E. Constructor :

  • Constructor cannot be final

F. Miscellaneous :

  • 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/declaring variables, methods or classes as final improves performances, as it get bind during compile-time itself

That’s all about final keyword in Java

 

References:

 

Read Also:

 

Happy Coding !!
Happy Learning !!

Interview Question and Answers on final keyword in Java
Java: instanceof operator or keyword