An inner class defined inside a method cannot access the method's local variables unless these local variables are marked final
.I've looked at other posts in stack-overflow and java code ranch but none of them seem to be exactly answering the question as to how marking variables final allows inner class to access local variables in the method.
class MyOuter {
private String x = "Outer";
void fly(final int speed) {
final int e = 1;
class FlyingEquation {
public void seeOuter()
{
System.out.println("Outer x is " + x);
}
public void display()
{
System.out.println(e);// line 1
System.out.println(speed);// line 2
}
}
FlyingEquation f=new FlyingEquation();
f.seeOuter();
f.display();
}
public static void main(String args[])
{
MyOuter mo=new MyOuter();
mo.fly(5);
}
}
Explanations I found to this :
local variables are stored on stack and as soon as the method call finishes the stack is popped up and local variables are inaccessible whereas final local variables are stored in data section of memory potentially allowing JVM
to access them even after the end of the method call. Where is the data section of memory
? I believe all local variables final or not are stored on the stack.When the method is removed from the stack the final variable will be removed with it. Is it that the value in the final variable is stored with the object in the heap ?
It does not support non-final fields as they could be changed, either by the method or the class and this is not supported because in reality there are two different fields/variables.
Accessing the Private Members Write an inner class in it, return the private members from a method within the inner class, say, getValue(), and finally from another class (from which you want to access the private members) call the getValue() method of the inner class.
If you want your inner class to access outer class instance variables then in the constructor for the inner class, include an argument that is a reference to the outer class instance. The outer class invokes the inner class constructor passing this as that argument.
Local Inner classes are not a member of any enclosing classes. They belong to the block they are defined within, due to which local inner classes cannot have any access modifiers associated with them. However, they can be marked as final or abstract.
Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class.
Marking a local variable as final
tells the compiler that its value is guaranteed not to change once it has been assigned. This makes it safe for the compiler to create a synthetic field inside the inner class and copy the value of the local variable into this synthetic field when the inner class instance is constructed. All reads of the local variable from inside the inner class code actually compile into reads of the synthetic field instead.
This trick wouldn't work for non-final variables as they might change after the inner class was instantiated, and the synthetic field would get out of sync with the original variable.
It's important to realise that all inner classes are tricks of the compiler - to the runtime JVM all classes (top-level, nested static, and inner) are treated the same.
During instantiation of the inner class, when both the method and the class are in scope, the inner class will make a copy of the variables which are constants, which means that the method can go out of scope, since the inner class is only using a copy of the variable. Check out this article.
Yes the final local variables are saved on the stack and is destroyed the moment the method is removed from the stack. As @Ian has suggested ,when the compiler sees the final keyword for the variable, it creates a copy of the value in the inner class object on the heap.
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