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不会报错

相关文章
|
存储 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
266 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
|
SQL Java 数据库连接
attempted to return null from a method with a primitive return type
attempted to return null from a method with a primitive return type
229 0
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而引发了方法参数值拷贝的问题
202 0
|
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
1610 0
Java - Lambda Error:Variable used in lambda expression should be final or effectively final
|
Android开发 Kotlin
【错误记录】Kotlin 编译报错 ( Not nullable value required to call an ‘iterator()‘ method on for-loop range )
【错误记录】Kotlin 编译报错 ( Not nullable value required to call an ‘iterator()‘ method on for-loop range )
286 0
【错误记录】Kotlin 编译报错 ( Not nullable value required to call an ‘iterator()‘ method on for-loop range )
delete attempted to return null from a method with a primitive return type (int)
今天被自己给蠢死了 今天在代码中遇到这个错误, 百度翻译一下:映射方法,从一org.system.mapper.child.chmorganizationexaminationmapper.delete返回零作为一个原始的方法的返回类型(int)。
2914 0

热门文章

最新文章