Final keyword in Java

Final is an important Keyword in Java.

Let’s just try to think what final could mean in plain English. As its name suggests, final is used to make entities final (do not get confused with Constants), so that,

  1. The user cannot change the value of a final variable.
  2. The user cannot override the final method.
  3. The user cannot inherit the final class.

So, basically Final keyword can be used with following entities.

  1. Class
  2. Method
  3. Variables
    • Class Variables
    • Instance Variables
    • Method Variables or Local Variables

For each of the above categories final keyword acts a little different, but the core concept remains the same: Do not let others change it (make it Final).

So let’s see one by one how final can be used with all the entities.

Final Class

Now, what is exactly a Class and how do you define it? We already have nice answers to these. You just need to spend your precious five minutes to go through. Click here to read.

So now if we say we want to use final keyword with a Class, which in other word means that we want make a class final. But what we are trying to achieve by making a class final?

Exactly as you guessed it right, that when we make a Class final, it cannot be sub-classed (inherited, extended, whatever you call it). This means the Class definition is now final and cannot be modified in any case by inheritance.

Final class is a dead end for inheritance hierarchy.

Now, why do we require a Final Class?

Most of the times we come across a case when we don’t want other programmers to extend and modify behavior of our class and we want our own class definition (definition of methods inside class) to be executed exactly the way we have written.

We should make a class final only if we need an absolute guarantee that none of the methods in that class will ever be overridden.

Can you give any best example of final class in Java library itself?

Exactly as you guessed it, it’s the String Class!

It has to be final. Just try to think of the catastrophic situation. If you cannot guarantee the behavior of the String class on different systems, which means that every different application start providing their own application specific behavior to the String class, by overriding the methods of String class.

If all programmers were free to extend the String class (and thus substitute their new String subclass instances where java.lang.String instances are expected), around 3 billion devices could have collapsed.

There’s a benefit of having non-final classes is such scenarios, where a method in a class you’re using is not that efficient or seems to be a problem for your application, but you don’t have the source code to do the required changes there itself and make things work out for you (which could be a very bad idea). So you can’t modify the source to improve the method, but alternatively, what you can do is, extend the class and override the method in your new subclass and substitute the subclass instance everywhere the original superclass instance is expected. But as we know of now, that if the class is final, you cannot override or create your own improved version of the superclass method and you’re badly stuck.

In practice, we almost never make a final class.

A final class goes against the key benefit of using OOPS, which is Extensibility. So, think thrice before making a class final, only if you really think that safety is the need of time and you don’t want any of the users to use a different version of your methods, which is why you want to make your class final. We write a final class as:

So, what happens if we try to extend a final class??

Exactly! We get a compilation error as:

Error – Can’t subclass final classes

Final Methods

A final method simply makes it final. By saying that we mean that it’s definition cannot be changed. In other words, it cannot be overridden in any of the subclasses.

It’s not like “Final methods cannot be inherited”. Of course it can be! In fact it will be inherited from superclass to subclass and subclass can use (call) it, but it cannot be overridden, which means that you will not be able to override (modify) the behavior of final method in any subclass.

Final keyword is often used to enforce the API functionality of a class.

Let’s see the Thread Example.

The Thread class has a method called isAlive() that checks whether a thread is still active. If you extend the Thread class, still there is no way that you can correctly implement this method yourself, since the designers have decided to make this method final.

It is just like an example we have seen earlier about String Class, where the whole class required to be final, but here we can extend the Thread class, which is non-final, but we cannot override isAlive() method, thus giving implementation security.

Final Variables

There are three types of variables in Java:

  1. Class Variables
  2. Instance Variables
  3. Method Variables

One general rule applicable to all the three types of variable is that, being final, once a particular value is assigned, it cannot be changed.

For example, the below code is INVALID, since the value assigned to a final primitive variable cannot be changed and remains the same forever.

Now let’s check out the below code:

By definition if you try to understand the above code, then the last two lines would seem very much wrong. But that’s not true. The first statement where we are explicitly setting the employeeId into the referenced Employee object is correct, whereas the other statement where we are reassigning the final Employee object reference variable to point to a new Employee object is wrong. This is because, we can update the data within the referenced object to any extent, but the reference variable marked as final cannot be reassigned to point to a different object.

Can final variables serve the purpose of Constants in Java?

Class variables are declared with static keyword and a single copy of each is created for multiple class instances, but still their values can be updated in static methods. Therefore a class variable cannot serve the purpose of a Java Constant. In contrast, instance variable declared with a final keyword would create a single copy for each class instance. So multiple class instances would also lead to multiple copies of the final instance variable. Therefore simply a final instance variable would also not suit to serve as a Java Constant. However, if we declare a variable as static final, will never allow us to modify it’s value and the assignment happens only once, while keeping a single copy for multiple class instances. So it lodges the feature of both static and final. In Java world, such static final variables are actually referred to as Constants. We declare Java Constants as:

Receive our updates to your inbox

Get more stuff like this
in your inbox

Subscribe to our mailing list and get interesting stuff and updates to your email inbox.