Can anonymous classes access unconfigured external objects in java 8?

Before java 8, the inner class could access external objects only if they were declared final. However, now when I run the sample code (below) on javaSE 1.8, there are no compilation errors and the program works fine.

Why did they change this and how does it work now?

Sample code from java 7 tutorial:

public class MOuter { private int m = (int) (Math.random() * 100); public static void main(String[] args) { MOuter that = new MOuter(); that.go((int) (Math.random() * 100), (int) (Math.random() * 100)); } public void go(int x, final int y){ int a = x + y; final int b = x - y; class MInner{ public void method(){ System.out.println("m is "+m); System.out.println("x is "+x); // supposedly illegal - 'x' not final System.out.println("y is: "+y); System.out.println("a is "+a); // supposedly illegal? - 'a' not final } } MInner that = new MInner(); that.method(); } } 
+5
source share
2 answers

In Java 7, the concept of an effective ending was introduced to support a more accurate retroning function , and its scope was expanded in Java 8 to cover local variables that are assigned only once, but are not actually declared final. They can be captured and used in lambda bodies or inner classes just as if they were declared final.

This is described in Section §4.12.4 Java Language Specification :

Some variables that are not declared final may instead be considered effective final.

A local variable or method, constructor, lambda, or exception parameter is actually final if it is not declared final , but it never arises as the left operand of an assignment operator ( §15.26 ) or as an operand of incrementing a prefix or postfix or ( §15.14 , §15.15 ) .

In addition, a local variable in the declaration of which there is no initializer is effective if everything is correct:

  • Not declared final.

  • Whenever this happens as the left operand of an operator job, it is definitely not assigned and definitely not assigned before the assignment; that is, it is definitely not assigned, and not specifically assigned after the right operand of the job ( §16 (Defined assignment) ).

  • This never happens as an operand of a prefix or postfix increment or decrement.

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

+7
source

It's still the same rule, except that the compiler forces you to explicitly define a variable as final . If this is truly final, you can access it. If this is not the case (that is, the compiler detects that the variable is being reassigned), then it will not compile.

+3
source

Source: https://habr.com/ru/post/1205639/


All Articles