Saturday, 18 June 2016

Use of final local variables in Java


We know why we declare a instance variable or class or a method as final. So that it cannot be extended or modified or overridden. But there are instances when we declare final local variables i.e declare variables inside method as final. Why would we do that? Let's see that.

To understand the usage I had asked this very question on Stack Overflow and Jon Skeet had answered it which made sense - 

There's one important "feature" of final local variables: they can be used in local (typically anonymous) inner classes. Non-final local variables can't be. That's the primary use of final for local variables, in my experience.

public void foo() {
    final String x = "hello";
    String y = "there";

    Runnable runnable = new Runnable() {
        @Override public void run() {
            System.out.println(x); // This is valid
            System.out.println(y); // This is not

Note that as a matter of style, some people like to use final even when they're not capturing the variable in a local inner class. I'd certainly be comfortable with final being the default, but a different modifier for "non-final", but I find that adding the modifier explicitly everywhere is too distracting.

NOTE : Well behind the scenes, the compiler generates an instance variable in the anonymous inner class and copies the value of the original variable when the instance is created. 

Java 8 Changes

The compiler is generating a class file from your inner class. A separate class has no way to refer to local variables. If the local variable is final ,Java can handle it by passing it to the constructor of the inner class or by storing it in the class file. If it weren’t effectively final, these tricks wouldn’t work because the value could change after the copy was made. 

Up until Java 7, the programmer actually had to type the final keyword. In Java 8, the “effectively final” concept was introduced. If the code could still compile with the keyword final inserted before the local variable, the variable is effectively final. 

Note same applies for Lambda expressions. To use a local variable in a lambda expression it needed to be final or effectively final.

As far as performance is considered there should not be much difference as JVM does it's own optimizations depending on the usage in code.

Nested classes in Java Summary

Related Links

t> UA-39527780-1 back to top