Variable used in lambda expression should be final or effectively final

简介: Variable used in lambda expression should be final or effectively final

8336305fedcb47d48f7dd6bdb3f2a6e5.png


意思 :

ambda表达式中使用的变量应该是final或者有效的final,也就是说,lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。

原因:

假定没有要求lambda表达式外部变量为final修饰,那么开发者会误以为外部变量的值能够在lambda表达式中被改变,而这实际是不可能的,所以要求外部变量为final是在编译期以强制手段确保用户不会在lambda表达式中做修改原变量值的操作。

在 Java 8 之前,匿名类中如果要访问局部变量的话,那个局部变量必须显式的声明为 final,如下代码在 Java 7 中是编译不过的

c495d69b88244a10a282f3891e8ffdbb.png


但是finalI并没有声明为final类型,然而代码却能够编译通过,这是因为 Java 8 之后,在匿名类或 Lambda 表达式中访问的局部变量,如果不是 final 类型的话,编译器自动加上 final 修饰符,即Java8新特性:effectively final。

6211f0b191a24f078aa6520f71793f73.png

java 中局部内部类和匿名内部类访问的局部变量必须由 final 修饰,以保证内部类和外部类的数据一致性。但从 Java 8 开始,我们可以不加 final 修饰符,由系统默认添加,当然这在 Java 8 以前的版本是不允许的。Java 将这个功能称为 Effectively final 功能。


可以在匿名内部类中直接使用非 final 变量,而 final 修饰的局部变量不能在被重新赋值


也就是说从 Java 8 开始,它不要求程序员必须将访问的局部变量显式的声明为 final 的。只要该变量不被重新赋值就可以。


总结一下,规则没有改变,Lambda 表达式和匿名内部类访问的局部变量必须是 final 的,只是不需要程序员显式的声明变量为 final 的,从而节省时间。  

public class Test {
    public static void main(String[] args) {
        String name = "C语言中文网";
        new Runnable() {
            @Override
            public void run() {
                System.out.println(name);
            }
        }
    }
}

java7报错,java8不会报错

相关文章
成功解决AttributeError: module 'numpy' has no attribute 'integer'
成功解决AttributeError: module 'numpy' has no attribute 'integer'
成功解决AttributeError: module 'numpy' has no attribute 'integer'
|
8月前
|
存储 Java 编译器
【Java异常】Variable used in lambda expression should be final or effectively final
【Java异常】Variable used in lambda expression should be final or effectively final
106 0
【Java异常】Variable used in lambda expression should be final or effectively final
VS2005 error C2864 only static const integral data members can be initialized within a class
VS2005 error C2864 only static const integral data members can be initialized within a class
|
11月前
|
数据库 OceanBase
RuntimeError: 'PluginContext' object has no attribute 'set_variable'
RuntimeError: 'PluginContext' object has no attribute 'set_variable'
93 2
Dart报The return type ‘bool‘ isn‘t a ‘void‘, as required by the closure‘s context
Dart报The return type ‘bool‘ isn‘t a ‘void‘, as required by the closure‘s context
|
Java 编译器
规避Variable used in lambda expression should be final or effectively final而引发了方法参数值拷贝的问题
规避Variable used in lambda expression should be final or effectively final而引发了方法参数值拷贝的问题
165 0
|
PyTorch TensorFlow 算法框架/工具
TensorflowConv2D:AttributeError: ‘int‘ object has no attribute ‘lower‘
TensorflowConv2D:AttributeError: ‘int‘ object has no attribute ‘lower‘
230 0
TensorflowConv2D:AttributeError: ‘int‘ object has no attribute ‘lower‘
TypeError: sequence item 0: expected string, int found
TypeError: sequence item 0: expected string, int found
|
Python
AttributeError: 'module' object has no attribute 'main'
AttributeError: 'module' object has no attribute 'main'
171 0
AttributeError: 'module' object has no attribute 'main'
|
Java
Java - Lambda Error:Variable used in lambda expression should be final or effectively final
Java - Lambda Error:Variable used in lambda expression should be final or effectively final
1506 0
Java - Lambda Error:Variable used in lambda expression should be final or effectively final