对于变量作用域的迷惑

img


很迷惑上面id为什么可以在匿名内部类的实现方法里用,运行完逻辑没错

可以把lambda表达式简单看做匿名内部类,在匿名内部类访问局部变量时,变量必须为final修饰。Java8中如果在匿名内部类中访问局部变量,该局部变量会被默认为final。
在lambad中使用局部变量id时,id会被默认为final,再次赋值会报错,你可以试下

这个id是updateWithFlavor方法中的局部变量,在这个方法范围内都是可以使用这个变量id,匿名内部类item也在updateWithFlavor方法里,因此item可以使用id。对于你的疑惑,为什么匿名内部类可以使用这个id?你可以把item当作new出来的类,是不是就可以想的通了呢。如果只是在内部类中使用局部变量,这个局部变量可以不用加final修饰,如果是在局部内部类中修改局部变量的话,则需要加final。对于修改局部变量为什么要加final才可以呢?我的理解是这样的:在方法中,局部变量存放到栈帧中,局部变量已经压栈,然后内部类存放到堆中,在内部类中改变已经压栈的引用地址(修改局部变量值),这个时候是不允许的,因为栈中已经压栈的局部变量引用地址无法修改。用final修饰的话,引用地址无法修改(比如说是引用的集合),但是可以改变引用集合中的值,就变相的改变了局部变量的值。

这个不是把id作为参数传进去的么

这种对于匿名内部类来说就是一个全局变量

可以去了解下类变量、成员变量和局部变量 这个问题跟匿名内部类没有关系