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 数据库连接 mybatis
MybatisPlus分页查询
本文讲解MybatisPlus分页查询的方法。
6013 0
MybatisPlus分页查询
|
安全 Java 数据安全/隐私保护
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
1527 1
|
数据处理
利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式
利用Stream流将取到的对象List<对象>形式数据进行分组统计转变成Map<分组条件,数量统计>形式
602 0
|
JSON 数据格式
解决POSTMAN传参报错,JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OB
解决POSTMAN传参报错,JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OB
解决POSTMAN传参报错,JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OB
|
存储 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
819 0
【Java异常】Variable used in lambda expression should be final or effectively final
6、Mybatis-Plus wrapper的使用
这篇文章详细介绍了Mybatis-Plus中Wrapper的使用,包括QueryWrapper和UpdateWrapper的基本概念、组装查询、排序、删除、修改条件的方法,以及如何设置条件优先级、组装SELECT子句和实现子查询等高级用法。
|
存储 缓存 Java
createTempFile方法详解
createTempFile方法详解
1012 1
解决lambda中必须为final的方式
解决lambda中必须为final的方式
1123 0
|
XML Java API
List与String相互转化方法汇总
本文汇总了List与String相互转化的多种方法,包括使用`String.join()`、`StringBuilder`、Java 8的Stream API、Apache Commons Lang3的`StringUtils.join()`以及Guava的`Joiner.on()`方法实现List转String;同时介绍了使用`split()`方法、正则表达式、Apache Commons Lang3的`StringUtils.split()`及Guava的`Splitter.on()`方法实现String转List。
2802 1
List与String相互转化方法汇总
|
SQL 关系型数据库 数据库
在 PostgreSQL 中使用 LIKE
【8月更文挑战第12天】
2567 1