Monday, April 24, 2023

When to make a method final in Java? Example

Hello guys, if you are wondering when to make a method final in Java then you have come to the right place. Earlier, I have told you when to make a method static and when to make private and today, I will teach you when to make a method final in Java. The final keyword in Java is not as mysterious as volatile or transient, but still, it creates a lot of doubts in programmers' minds. I often receive questions like, When to make a method final in Java or When to make a method static in Java, later I answered in my earlier post. Questions like this are not trivial, knowing what a keyword does is just a small part of mastering that functionality. Similar to the real world, where knowing that a sword can cut a lot of things is not enough for a warrior to survive, you need to know how to use that and more importantly, use it effectively. 

The final keyword can be applied to a class, methods, and variable and has a different meaning for each of them, but the motive remains the same, it states completeness, it opposes change. For example, the final class can not be extended, the value of a final variable cannot be changed and a final method can not be overridden in Java.

This gives you the first hint when to make a method final in Java, obviously to prevent sub class from changing its definition, technical preventing it from overriding. There are a lot of clues on How to use the final keyword on methods in Java API itself, one of the prime examples of this java.lang.Object class, which declares a lot of method final including wait method with a timeout.

Another example of making a method final is the template method, which outlines an algorithm in the Template method design pattern. Since, you don't want a subclass to change the outline of the algorithm, making it final will prevent any accidental or malicious overriding. In this tutorial, we will learn a few things, which will help you to effectively use final keywords with Java methods.



Which methods should be made final in Java? Examples

One of the best practices which I learned from clean code is about good designs, which mandates and ensures things, rather than listing some guidelines. A prime example of this is the clone() method, whose correct implementation depends upon following some guidelines, which is not ensured by the system.

By making a Java method final, you not only indicate but also ensures that no one can change its definition. This is particularly important while dealing with sensitive method, which deals with security and critical functionalities.

The Template method pattern is a good example of when to make a method final. In the template method pattern, the outline of the method is captured in one method but hooks are provided to add flexibility in implementation.

By making the template method final, we ensure that steps defined in algorithms are exactly followed by each class, but gives them the flexibility to define steps in their own term.

By the way, in Java, making a class final, automatically ensures that all it's methods can not be overridden, which is equivalent to making the final. Making a class final is also an important step to create an Immutable class in Java.

Here are few guidelines, which can be helpful to decide, when to make a method final :

1. Methods which are called from constructor should be final, otherwise, a subclass may override and alter the behavior of the method, which may result in surprise and undesirable behavior.

2. Consider making the performance-critical method final, this given compiler more opportunity to optimize it. The compiler may inline or cache such methods because they can not be changed during the application lifetime.  Though modern JIT is even capable of the in-lining non-final method, if they think it can result in performance gain and it's not overridden, making a method final can do this in-lining even before JIT comes into the picture.

3. Sensitive methods, whose behaviors are deemed complete and which are not supposed to be overridden, should be final.

4. Consider making template methods final, while using Template method design pattern.

When to make a method final in Java? Example


In short, making a method final is mainly driven by design and safety requirements. Though performance can also be considered one of the reasons, it is not the main reason in today's Java world of advanced JIT. It's also a good idea to document, why you made a method final, that will help develop, who will maintain your code. 

There is also another doubt about making a private method final or not. Since the private method can not be overridden, neither in a subclass, where it's not accessible nor in inner class where it's accessible, because they are bonded using static binding using the class name. Making a private method final doesn't provide any additional value.


That's all on this Java tutorial about when to make a method final in Java. The main reasoning behind making a method final is to prevent it from being overridden by subclasses. By making a method final, you not only indicate but also ensures that your tried and tested method is not overridden. As a best practice of prevention, any security-sensitive method related to authentication and authorization should be final. 

Similarly, critical methods, which define critical functionality like template method must be final. Last, but not least, any method which is called from constructor must be final to avoid any surprise, which may result due to accidental or malicious overriding in a subclass.


7 comments :

Anonymous said...

can u share me ur knowledge of java performance and tuning with optimizer(how jvm working with bytecode with taking the consideration with performance ) it thr any article or books...ple lemme knw ...........Thnaks in advance

Anonymous said...

You must absolute make a method final if it is doing any kind of security checks, because non-final method , who performs security checks can be overridden in a way that bypass security. For example, a child class can override a non-final method to bypass security checks done in the parent class. Following code is bad for this reason

class SensitiveClass{

public perform(SensitiveAction e){
doSecurityCheck();
// do something

}

protected void doSecurityCheck() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new sesnsitivePermission("sesitiveAction"));
}
}

}

SARAL SAXENA said...

@Javin Nice article just want to add that..

Final keyword has a numerous way to use:

A final class cannot be subclassed.
A final method cannot be overridden by subclasses
A final variable can only be initialized once
Other usage:

When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class
A static class variable will exist from the start of the JVM, and should be initialized in the class. The error message won't appear if you do this.

Kabir said...

I was asked in a interview that when to use final method in Java and when I gave example of template method pattern, interviewer asked me that it's better to make the template method private than final, because making it private, makes it final anyways but also hide it from outside world, unlike final which doesn't hide it. So now my question is what is different between private and final and when should one use private and final in Java?

Anonymous said...

their is another reason which is why I suggest you always use final

nothing to do with Java itself more developer productivity and reducing bugs, specifically due to when working with source control and merging code, or applying patches

if you use final all the time it will break the compile time build after its merged and built. if variables are reused so this highlights potential issues for you to review, the solution might be to removal finally for the instance and I've have no issue with variables not being final

I've recently merged in 3 branches of new functionally that was developed 6-9 months ago, and developers have moved to new projects. code merged fine and looked okay, integration highlighted issues and simply having final would have save a week's effort essentially recoding all the meres

Anonymous said...

Just a heads up, you have a little grammar mistake in the 5th paragraph: "but also ensures that no one can it's definition"

javin paul said...

Thanks for heads=up, *Change* was missing there, added now.

Post a Comment