What is “effectively final” in Java?

Let’s say you don’t want a variable value to be changed once it is initialized.

How to achieve this in Java?

By declaring the variable as final.

Now the variable becomes a constant and the compiler will complain if it is modified anywhere.

There is one more concept of “final” in Java , which is termed as effectively final.

You may run across this if you try to access a variable value inside a lambda expression (if the variable is declared outside the lambda expression and its value is changed).

Also you can face this issue when you try to access a variable declared in the outer scope of a local class after changing its value.

Why is this so ?

What is this effectively final?

Java allows only final variables to be accessed inside lambda expressions and local classes.

But you don’t have to declare those variables as final!

All you have to make sure is that you don’t change the variable value once it is first assigned.

Then Java will treat it as a final variable even though you haven’t explicitly mentioned it so !

“An effectively final variable is a variable which is assigned a value only once and never again changed in your program”

Consider the below code:

	public int test() {

		final int i = 5;

		Function<Integer, Integer> function = a -> a + i;

		return function.apply(6);

	}

In the above code , we are trying to access the variable “i” inside the lambda expression “a => a+i”.

It will work fine since you can access only final variables inside a lambda expression.

Java doesn’t want a variable to be changed inside a lambda expression.

What you send in is what you will get out and this prevents bugs.

But then consider the below code:

	public int test() {

		int i = 5;

		Function<Integer, Integer> function = a -> a + i;

		return function.apply(6);

	}

The above code will also work though you have not declared the variable i as final.

Why is this so?

The same reason as mentioned earlier , even though the variable is not declared as final , the variable value is never changed once it is assigned a value of 5, so Java treats it as “effectively final”.

Now consider the below code:

	public int test() {
	
			int i = 5;
			
			i = 8;
	
			Function<Integer, Integer> function = a -> a + i;
	
			return function.apply(6);
	
		}


I am trying to change the value of “i” in the above code to 8.
And immediately the compiler complains:

The local variable should be either final or effectively final (value not changed once assigned).

The same error happens if you try to change a local variable before accessing it inside a local class:

The above code has a local class EffectivelyFinalLocal declared inside the method test.

The variable local is declared and assigned a value in the method test.

And later an attempt is made to change its value before accessing it in the local class.

And the compiler gives the same error!

That’s it!


Posted

in

,

by

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading