Before java 8 an inner class could access outer objects only if they were declared final. However now when I run example code (from below) on javaSE 1.8 there is no compilation error and program runs fine.
Why did they change that and how does It work now?
Example 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();
}
}
An anonymous class has access to the members of its enclosing class. An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.
Anonymous object in Java means creating an object without any reference variable. Generally, when creating an object in Java, you need to assign a name to the object. But the anonymous object in Java allows you to create an object without any name assigned to that object.
18) Which of the following is true about the anonymous inner class? Explanation: Anonymous inner classes are the same as the local classes except that they don't have any name. The main use of it is to override methods of classes or interfaces.
For regular/normal class, we can write any number of constructors but we can't write any constructor for anonymous Inner class because the anonymous class does not have any name and while defining constructor class name and constructor name must be same.
In Java 7 the the concept of effectively final was introduced to support the "more precise rethrow" feature, and its scope was expanded in Java 8 to cover local variables that are assigned only once, but not actually declared final.
These can be captured and used in lambda bodies or inner classes just as if they were declared final.
This is covered in section §4.12.4 of the Java Language Specification:
Certain variables that are not declared
final
may instead be considered effectively final.A local variable or a method, constructor, lambda, or exception parameter is effectively final if it is not declared
final
but it never occurs as the left hand operand of an assignment operator (§15.26) or as the operand of a prefix or postfix increment or decrement operator (§15.14, §15.15).In addition, a local variable whose declaration lacks an initializer is effectively final if all of the following are true:
It is not declared
final.
Whenever it occurs as the left-hand operand of an assignment operator, it is definitely unassigned and not definitely assigned before the assignment; that is, it is definitely unassigned and not definitely assigned after the right-hand operand of the assignment (§16 (Definite Assignment)).
It never occurs as the operand of a prefix or postfix increment or decrement operator.
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 declaredfinal
in a valid program becomes effectively final if thefinal
modifier is removed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With