Effectively final - Inner classes access

元气小坏坏 提交于 2021-01-27 20:45:08

问题


Inner classes only have access to final or effectively final variables. I don't understand though, why an instance variable can be accessed no matter what, but local variables and method parameters need to be at minimum effectively final?

Consider the following code:

public class BookStore {   

    private static final int taxId = 300000;   
    public String name;   

    public String searchBook(final String criteria) {      
        int count = 0;      
        int sum = 0;      
//      name = "";      I can uncomment this -> no compile error
        class Enumerator {         
            String interate(int k) {    
                System.out.println(name);
                System.out.println(sum);
                return "";         
            }             
        }            
//      sum++;      If I uncomment this, a compile error will be thrown.
        return "";
    }

}

Why is it necessary that local variables + method arguments need to be effectively final?


回答1:


It's because of the scope of the local variables. Their scope is the method in which they are declared. Once execution has left the method, they are no longer valid. However, an inner class such as your Enumerator class can live on past the method execution, e.g. by returning a reference to a class instance.

Thus, the Enumerator class and its methods can be accessed outside of the method in which it is declared. At that point, it needs to assume that the local variables it referenced have the same value they had when execution instantiated the class.

For instance variables, the scope of these and of the inner class is the same - they are both available as long as the parent class instance exists.




回答2:


It’s all about the value which is captured when the instance is created. Inner classes in an instance context always capture the immutable outer this reference¹, through which the instance fields can be accessed, mutable or not. In contrast, local variables can only be captured by their value, hence, the variable must not change, to be consistent with the captured value.

This is a design decision. Technically, it would be no problem to a) allow subsequent mutations that are not reflected by the inner class’ state or b) wrap every shared local variable into an object to allow mutations like with instance fields of the outer class, but neither, allowed inconsistency nor local variables that aren’t actually local, were deemed acceptable by the language designers.

¹ This differs from lambda expressions which only capture this when actually accessing instance variables



来源:https://stackoverflow.com/questions/39889003/effectively-final-inner-classes-access

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!