blog

Home / DeveloperSection / Blogs / The final keyword: final methods

The final keyword: final methods

Simond Gear1310 17-May-2016

Just the way we create final classes, we create final methods that cannot be overridden in the subclasses. To explain the purpose behind this, let’s look at an example. In Java, the Object class includes methods such as wait and notify. These are system-level methods that implement core language capabilities. If Java allowed users to substitute these methods with their own overridden implementations, the semantics of the language itself would be altered. Therefore, these methods are declared as final.

If we do not want a subclass of our class to override our method implementation, you mark the method as final. The following code snippet shows a declaration of a final method:

public class MyClass {
...
                  public final void myMethod() {
                      ...;
                   }
}

 The method myMethod has been declared final and cannot be overridden in a subclass of MyClass. For example, the following declaration will generate a compile-time error:

public class YourClass extends MyClass {
...
                      public void myMethod() {
                           ...;
                       }
}


There are three benefits to making a method final. The first benefit, as we have seen so far, is to explicitly prevent overriding it in a subclass. As mentioned earlier, there is a very valid reason not to allow the wait and notify methods of the Object class to be overridden in the subclasses.

The second benefit is that it tells the compiler that for a call to this method, dynamic binding isn’t necessary, which potentially results in a slightly more efficient code. Static binding is always more efficient than dynamic binding. In the case of static binding, the method call is resolved at compile time, whereas in case of dynamic binding, the runtime resolves the method call.

The third benefit also results in better efficiency—marking a method final allows the compiler to turn any call to that method into an inline call. When the compiler sees a final method call, it can, at its discretion, skip the normal approach of inserting code via the method call mechanism.

A call mechanism consists of pushing the method arguments on the stack, jumping to the method code, executing it, hopping back to the caller, cleaning off the stack arguments, and finally dealing with the returned value. Instead of this, the compiler now can replace the method call with a copy of the actual code in the method body. This is called inlining and eliminates the overhead of a method call. However, if the method is big, the benefit of saving time in calling and returning from a method will be dwarfed by the amount of time spent inside the method.

Therefore, generally small methods benefit from inlining. The inlining benefits are not necessarily restricted to the size of the method, however, because inlining a method often leads to further optimizations, such as the elimination of dead code or more inlining.


Updated 14-Mar-2018

Leave Comment

Comments

Liked By