The final keyword in Java is a fundamental concept that allows variables, methods, and classes to be declared as “final,” indicating that they cannot be modified or extended further. This keyword introduces immutability and enforces restrictions on inheritance, making it a powerful tool in Java programming.
In this outline, we will explore the various aspects of the final keyword in Java, including final variables, methods, classes, arguments, and its impact on thread safety.
Where can we use final keyword ?
final
keyword in java can be used in various contexts to indicate different kinds of immutability or restrictions.
Final Classes: Declare a class as final to prohibit subclassing or extension. Typically used for utility classes or classes with a specific implementation that should not be modified.
Final Methods:
Declare a method as final to prevent overriding by subclasses. Subclasses can invoke the method but cannot provide a different implementation.
Final Variables:
- Local Variables: Declare them as final to prevent value modification after assignment.
- Instance Variables: Mark them as final to enforce assignment either during declaration or within the constructor, with no modification allowed afterward.
- Class Variables/Static Variables: Declare them as final to create constants that have the same value across all class instances.
Final Arguments:
Use final with method parameters to indicate that their values cannot be modified within the method.
Final Classes
The Class marked with final keyword can not be inherited by a sub class. In simple words, the final class can not be extended.
public final class FinalClass {}
You can not do the below.
class childChild extends FinalClass{}
You will get compilation error.
Final keyword is typically used for classes that are not intended to be extended, such as utility classes or classes that have a specific implementation that should not be modified.
Final Methods
The final method defined in the parent class cannot be overridden in the child class.
You will get compiler error if you try to do so.
Scenarios for using Final Methods:
- Prevent Method Overriding: Use
final
methods when you want to prohibit subclasses from changing the implementation of a method defined in the superclass. - Preserve Method Contracts: Mark methods as
final
to ensure that subclasses adhere to a specific behavior or contract defined by the superclass. - Security and Encapsulation: Protect critical methods from being overridden to maintain the integrity of a class’s functionality, especially in security-sensitive contexts.
Final Variables
Final variables in Java are variables that are declared with the final
keyword and cannot be changed or reassigned once they are initialized. They hold a constant value throughout the program execution.
package com.java.core;
public class TestClass {
private String name;
public TestClass(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
TestClass nonFinalReference = new TestClass("Gyan");
final TestClass finalReference = nonFinalReference;
System.out.println("Before Name via finalReference:" + finalReference.name);
System.out.println("Before Name via nonFinalReference:" + nonFinalReference.name);
finalReference.setName("Rochit");
System.out.println("After Name via finalReference:" + finalReference.name);
System.out.println("After Name via nonFinalReference:" + nonFinalReference.name);
}
}
Before Name via finalReference:Gyan
Before Name via nonFinalReference:Gyan
After Name via finalReference:Rochit
After Name via nonFinalReference:Rochit
Let’s see what happened in the above example
TestClass nonFinalReference = new TestClass(“Gyan”);
The above line create a non final reference variable nonFinalReference and refers it to a TestClass Object with name as “Gyan”
final TestClass finalReference = nonFinalReference;
The above creates a final reference variable finalReference and refers to the earlier created TestClass Object.
Now both nonFinalReference and finalReference refer to the same TestClass Object.
finalReference.setName(“Rochit”);
The above updates the name of the TestClass Object to Rochit via the finalReference.
Note:The only thing that cannot do is to make the finalReference refer to some Other TestClass Object.
static final variable in Java
Here’s an example of a static final variable in Java:
public class Constants {
public static final int MAX_VALUE = 100;
public static final String DEFAULT_NAME = "John Doe";
// Other class members and methods...
}
In this example, we have a class called Constants
that contains static final variables. The MAX_VALUE
variable is declared as an int
and holds the maximum allowed value, which is set to 100. The DEFAULT_NAME
variable is declared as a String
and holds the default name “John Doe”.
Since these variables are declared as static and final, their values cannot be modified once assigned. They can be accessed using the class name, Constants.MAX_VALUE
or Constants.DEFAULT_NAME
, without creating an instance of the class.
These static final variables can be useful when you have values that are constant and shared across multiple instances or throughout the program. They provide a convenient way to define and use constants in your Java code.
Some scenarios where using final
variables can be useful:
- Constants: If you have a value that should remain constant throughout your program, you can declare it as a
final
variable. This ensures that the value cannot be modified after it is assigned. - Thread Safety: In a multithreaded environment, using
final
variables can contribute to thread safety. Once afinal
variable is assigned a value, it guarantees that all threads will see the same value without the risk of it being modified concurrently. - Immutable Objects: If you want to create immutable objects, you can declare the fields as
final
. This guarantees that the fields’ values cannot be changed after the object is constructed, leading to more predictable and reliable behavior. - Lambda Expressions and Anonymous Classes: When using lambda expressions or anonymous classes, local variables referenced within them must be effectively final (meaning they are not reassigned). By explicitly marking such variables as
final
, you can ensure their immutability and avoid potential issues
Final arguments in a method
When writing final arguments in a method, it typically refers to defining parameters as final
within the method signature. The final
keyword in Java indicates that the parameter cannot be reassigned within the method body. Here’s an example of a method with final arguments:
public void process(final int num1, final String str) {
// Method body
// The values of num1 and str cannot be changed within this method
}
In this example, the num1
and str
parameters are declared as final
, which means these parameters can’t be reassigned within the method.
Using final
arguments can be useful in scenarios where you want to enforce immutability or ensure that the values of specific parameters remain unchanged throughout the method execution.
Benefits of Using final keyword in Java
Using the final keyword in Java provides several benefits. Here are some key advantages:
- Immutability: By marking variables, method parameters, or method results as final, you enforce immutability. This helps maintain data integrity and prevents accidental modifications, leading to more reliable and bug-free code.
- Security: The final keyword helps enhance security by preventing sensitive data or critical methods from being modified or overridden. It ensures that important aspects of your code remain unchanged and protected.
- API Design: Final keyword can be useful in API design to establish clear contracts and prevent unintended modifications by users of your API. By marking certain elements as final, you communicate their intended usage and behavior, promoting better understanding and usage of your API.
- Performance Optimization: The final keyword in Java allows the compiler to apply certain optimizations, such as inlining method calls, which can lead to improved performance. By indicating that a method, class, or variable is final, you provide hints to the compiler for potential optimizations.
- Code Readability: Using the final keyword in Java makes your code more readable and self-explanatory. It acts as a documentation mechanism, clearly indicating that certain elements should not be modified, overridden, or extended, which aids in code comprehension and maintainability.
- Thread Safety: Final variables and methods contribute to thread safety by ensuring consistent and synchronized access. Once assigned, final variables can be safely shared among multiple threads without the need for synchronization mechanisms.
- Compiler Warnings and Error Prevention: The final keyword can help catch potential errors at compile-time. For example, if you attempt to modify a final variable or override a final method, the compiler will generate an error, preventing such mistakes from going unnoticed.
FAQs:
What does the final keyword mean in Java?
The final keyword in Java indicates immutability or restrictions, preventing variables, methods, classes, or method parameters from being modified or overridden.
How is the final keyword used with variables?
The final keyword can be used with variables to make them constants. Once assigned, their values cannot be changed.
Can final variables be modified in Java?
No, once a final variable is assigned a value, it cannot be modified. It remains constant throughout the program.
What is the purpose of using final methods in Java?
Final methods are used to prevent subclasses from overriding them. Their implementation remains the same across the inheritance hierarchy.
Can final classes be extended in Java?
No, final classes cannot be subclassed or extended. They are designed to be used as-is, without any modifications.
When should I use the final keyword with method parameters?
The final keyword with method parameters indicates that their values cannot be modified within the method. Use it to enforce immutability and prevent accidental changes.
Can final methods be overloaded in Java?
Yes, final methods can be overloaded in Java. Overloading refers to having multiple methods with the same name but different parameters.
Is it mandatory to use the final keyword with constants in Java?
It is not mandatory to use the final keyword with constants in Java. However, using final provides clarity and ensures that the constant values remain unchanged.
Can a final variable be reassigned in a constructor?
Yes, a final variable can be assigned a value within a constructor, as long as it is assigned only once. Once assigned, its value cannot be modified.
Can final classes have non-final methods in Java?
Yes, final classes can have non-final methods. The final keyword applies to the class itself and restricts subclassing, but it doesn’t restrict the individual methods within the class.
What is a static final variable in Java?
A static final variable is a class-level variable that is declared as final and holds a constant value. It is shared among all instances of the class and remains unchanged throughout the program’s execution.
How is a static final variable different from a regular final variable?
The main difference is that a static final variable is associated with the class itself, while a regular final variable is associated with an instance of the class. Static final variables are accessed using the class name, whereas regular final variables are accessed using an instance reference.
Conclusion
In conclusion, the final keyword in Java provides a powerful mechanism to enforce immutability and restrictions within the language. By using the final keyword in Java, developers can declare final variables, methods, classes, and method parameters, each serving different purposes.
Overall, the final keyword in Java enables developers to create immutable values, secure class hierarchies, and provide clear API contracts. By leveraging the final keyword in Java, programmers can enhance code reliability, maintainability, and performance, making it an essential tool in the Java programming language.