Monday, 20 July 2015

What is Effectively Final variable of Java 8

Apart from big three, Lambda expression, Stream API and new Date and Time API, Java 8 has also introduced a new concept called "effectively final" variable. A non final local variable or method parameter whose value is never changed after initialization is known as effectively final. Its very useful in the context of lambda expression. If you remember, prior to Java 8, we cannot use a non final local variable in anonymous class. If you have to access a local variable ( a method parameter or a variable decreed in the method itself) in Anonymous class, you have to make it final. This restriction is lessen a bit with lambda coming up. Java designers have take the need to make local variable final if its not changed once initialized. This is really a good proactive step from them, they must have anticipated frequent use of lambda expressions as compared to minimal use of Anonymous class and realized the pain to declare a local variable final every time in order to access it inside lambda. The rule has not changed, any local variable still has to be effectively final to be used inside lambda expression or anonymous inner class, its just that you don't need to use final keyword anymore, saving a few keystroke. If you don't follow this then you will get following error : "local variables referenced from a lambda expression must be final or effectively final". Let's see some examples of effectively final variables with lambdas and anonymous class and how it make life of Java developer easy.



How to use Effective final variable in Java 8

Effectively Final variable of  Java 8
Effective final variable is nothing but a gift from Java designer to us, Java developers. There is hardly any difference between a final local variable and a effectively final variable, once declared you cannot change values of both of them. If you do, compiler will raise error. Here is an example of using effective final variable in Java 8, if you run the same program with Java source 1.7, your program will not compile and give error "local variable nonFinal is accessed from within inner class; needs to be declared final" because nonFinal is a local variable but not final. BTW, if you run the same program in Java 8 it will run fine and produce the output in form of the print statement we have given. Now in Java 8, if you try to reassign a new value to our non-final local variable, compiler will again complain with error "local variables referenced from an inner class must be final or effectively final". This line is commented in our example, you can try by yourself by uncommeting it.

package test;

/**
 * Java Program to demonstrate effectively final variable in Java 8.
 *
 * @author Javin Paul
 */
public class EffectiveFinalDemo{

    public static void main(String args[]) {
        String nonFinal = "I am non final local variable";
        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("Using non-final local variable inside anonymous class in Java");
                System.out.println("Value of non-final variable is : " + nonFinal);

                // compile time error - must be final or effective final
                // nonFinal = "Can I change non-final variable inside anonymous class";
            }
        };

        Thread t = new Thread(r);
        t.start();
    }

}

If you run this program it will print following line in Java 8 :
Using non-final local variable inside anonymous class in Java
Value of non-final variable is : I am non final local variable

Now let's see how to use effectively final variable in lambda expression in Java 8 :
public class EffectiveFinalWithLambda{

    public static void main(String args[]) {
        String effectiveFinal = "I am non final local variable";
        Runnable r = () -> {
            System.out.println("Value of effectively variable is : " + effectiveFinal);
        };

        Thread t = new Thread(r);
        t.start();
    }

}

You can see that we can access "effectiveFinal" variable without any issue in lambda expression. Now just try to assign this variable a new value before lambda, just to make it non final and see what happens, you will receive error "local variables referenced from a lambda expression must be final or effectively final".


That's all about what is effectively final variable of Java 8 and how to use it in your Java program. Now it become one more thing to note about final variables in Java. Remember till Java 7, you cannot use a non final local variable inside anonymous class, but from Java 8 you can.  Concept of Effective final variables in only available from Java 8 onward. A variable is considered effective final if it is not modified after initialization in local block. This means you can now use local variable without final keyword inside anonymous class or lambda expression, provided they must be effectively final. In short, you can save some keystroke while declaring local final variables indented to be used by anonymous class. There is no real difference between a final local variable and effectively final variable of Java 8, once initialized you cannot change value of both of them.

If you like this tutorial and hungry to learn more about new features and goodies from Java 8, check out my following amazing articles :
  • 10 Good Tutorials to Learn Java 8 (list)
  • How to filter List in Java 8 using Predicates? (solution)
  • Java 8 Comparator Example with Lambdas (example)
  • 10 Java 7 Feature to revisit before you startswith Java 8 (list)
  • How to Read File in Java 8 in one line? (example)
  • What is default method in Java 8. (tutorial)
  • How to use Map function in Java 8 (example)
  • 10 Examples of Stream API in Java (examples)
  • How to use Lambda Expression in Place of Anonymous class in Java 8 (solution)
  • Java 8 tutorials and Books for FREE (resources)
  • Are you ready for Java 8 Certification? (read more)

No comments:

Post a Comment