Effectively final java что это
Перейти к содержимому

Effectively final java что это

  • автор:

Effectively Final Variables in Java

Java 8 introduced a new term : effectively final variables. A variable which is not declared as final but whose value is never changed after initialization is effectively final.

The above code does not compile, the java compiler gives the below error message for variable i.

To fix the compile error, loop variable i, which is not final can be assigned to an effectively final variable:

Java 8 compiler can detect that the variable counter remains unchanged and we can use a non-final local variable inside a lambda expression. If the value of the captured variable changes the compiler gives the same error as the above sample.

Вот так final…

Что можно сказать про массив, когда он объявлен final ?

Известно, что класс String — immutable , класс объявлен final , значение строки хранится в массиве char , который отмечен ключевым словом final .

Т.к. массив – это объект, то final означает, что после присвоения ссылки на объект, уже нельзя ее изменить, но можно изменять состояние объекта.

Да, можно. Ключевой момент – это понимание использования колючего слова final с объектами. Для подмены значения использует ReflectionAPI.

Difference between final and effectively final

I’m playing with lambdas in Java 8 and I came across warning local variables referenced from a lambda expression must be final or effectively final . I know that when I use variables inside anonymous class they must be final in outer class, but still — what is the difference between final and effectively final?

14 Answers 14

. starting in Java SE 8, a local class can access local variables and parameters of the enclosing block that are final or effectively final. A variable or parameter whose value is never changed after it is initialized is effectively final.

For example, suppose that the variable numberLength is not declared final, and you add the marked assignment statement in the PhoneNumber constructor:

Because of this assignment statement, the variable numberLength is not effectively final anymore. As a result, the Java compiler generates an error message similar to «local variables referenced from an inner class must be final or effectively final» where the inner class PhoneNumber tries to access the numberLength variable:

Suresh Atta's user avatar

I find the simplest way to explain «effectively final» is to imagine adding the final modifier to a variable declaration. If, with this change, the program continues to behave in the same way, both at compile time and at run time, then that variable is effectively final.

This variable below is final, so we can’t change it’s value once initialised. If we try to we’ll get a compilation error.

But if we create a variable like this, we can change it’s value.

But in Java 8, all variables are final by default. But the existence of the 2nd line in the code makes it non-final. So if we remove the 2nd line from the above code, our variable is now «effectively final».

So.. Any variable that is assigned once and only once, is «effectively final».

According to the docs:

A variable or parameter whose value is never changed after it is initialized is effectively final.

Basically, if the compiler finds a variable does not appear in assignments outside of its initialization, then the variable is considered effectively final.

For example, consider some class:

5gon12eder's user avatar

‘Effectively final’ is a variable which would not give compiler error if it were to be appended by ‘final’

From a article by ‘Brian Goetz’,

Informally, a local variable is effectively final if its initial value is never changed — in other words, declaring it final would not cause a compilation failure.

Ajeet Ganga's user avatar

A variable is final or effectively final when it’s initialized once and it’s never mutated in its owner class. And we can’t initialize it in loops or inner classes.

Final:

Effectively Final:

Note: Final and Effective Final are similar(Their value don’t change after assignment) but just that effective Final variables are not declared with Keyword final .

Vishwa Ratna's user avatar

samadadi's user avatar

When a lambda expression uses an assigned local variable from its enclosing space there is an important restriction. A lambda expression may only use local variable whose value doesn’t change. That restriction is referred as «variable capture» which is described as; lambda expression capture values, not variables.
The local variables that a lambda expression may use are known as «effectively final«.
An effectively final variable is one whose value does not change after it is first assigned. There is no need to explicitly declare such a variable as final, although doing so would not be an error.
Let’s see it with an example, we have a local variable i which is initialized with the value 7, with in the lambda expression we are trying to change that value by assigning a new value to i. This will result in compiler error — «Local variable i defined in an enclosing scope must be final or effectively final«

Effective final topic is described in JLS 4.12.4 and the last paragraph consists a clear explanation:

If a variable is effectively final, adding the final modifier to its declaration will not introduce any compile-time errors. Conversely, a local variable or parameter that is declared final in a valid program becomes effectively final if the final modifier is removed.

What is Effectively Final variable of Java 8? Example

Apart from the big three, Lambda expression, Stream API, and new Date and Time API, Java 8 has also introduced a new concept called the «effectively final» variable. A non-final local variable or method parameter whose value is never changed after initialization is known as effectively final. It’s very useful in the context of the lambda expression. If you remember, prior to Java 8, we cannot use a non-final local variable in an anonymous class. If you have to access a local variable ( a method parameter or a variable decreed in the method itself) in the Anonymous class, you have to make it final . This restriction is relaxed a bit with lambda coming up. Java designers have taken the need to make local variable final if it’s 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 the minimal use of Anonymous class and realized the pain to declare a local variable final every time in order to access it inside the 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, it’s just that you don’t need to use the final keyword anymore, saving a few keystrokes.

If you don’t follow this then you will get the 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 makes the life of Java developers easy.

Btw, if you are not familiar with new Java 8 features like Effectively final variable then I suggest you first go through comprehensive and up-to-date Java courses from Udemy and Coursera. These are good resources to learn new Java features.

How to use Effective final variable in Java 8

Effectively Final variable of Java 8

The effective final variable is nothing but a gift from Java designers to us, Java developers. There is hardly any difference between a final local variable and an effectively final variable, once declared you cannot change the values of both of them.

If you do, the compiler will raise an error. Here is an example of using an effectively 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 the 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, the compiler will again complain about the 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 uncommenting it.

If you run this program it will print the following line in Java 8:

Now let’s see how to use an effectively final variable in lambda expression in Java 8:

You can see that we can access «effectiveFinal» variable without any issue in the 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 an error «local variables referenced from a lambda expression must be final or effectively final» .

That’s all about what is the effectively final variable of Java 8 and how to use it in your Java program. Now it becomes one more thing to note about final variables in Java. Remember till Java 7, you cannot use a non-final local variable inside an anonymous class, but from Java 8 you can.

The concept of Effective final variables is only available from Java 8 onward. A variable is considered an effective final if it is not modified after initialization in the local block.

This means you can now use the local variable without the final keyword inside an anonymous class or lambda expression, provided they must be effectively final. In short, you can save some keystrokes while declaring local final variables intended to be used by the anonymous class.

There is no real difference between a final local variable and an effectively final variable of Java 8, once initialized you cannot change the value of both of them.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *