Lambda 局部变量 final

Lambda表达式在Java中提供了一种简洁的函数式编程方式,允许函数作为参数传递。然而,为了确保代码的一致性和正确性,Lambda表达式引用的局部变量必须是final或effectivelyfinal,防止值的变化导致不一致。这一限制避免了潜在错误,且有助于代码的可读性。当变量是对象时,其状态仍可变,但不能重新赋值。
摘要由CSDN通过智能技术生成

Hello JJH!
在 Java 中,Lambda 表达式是一种轻量级的函数式编程方式,它允许你将一个函数作为参数传递给另一个函数或方法,并在需要时创建一个实现该函数的对象。Lambda 表达式可以让代码更加简洁和易读,但是在使用 Lambda 表达式时,需要注意局部变量必须是 final 或 effectively final。

effectively final 是指没有显式声明为 final,但是在后面的使用中没有发生改变

  • 这是因为 Lambda 表达式的实现方式会对变量的生命周期进行限制。当你在 Lambda 表达式中引用一个变量时,Lambda 表达式会创建一个对该变量的副本,并将其保存在 Lambda 对象中。但是,如果该变量在 Lambda 表达式中被改变,那么原始变量和副本变量的值就会不同,这会导致代码出现错误或不一致的行为。
  • Lambda表达式是一个语法糖,会被编译生成为当前类的一个私有方法,Lambda表达式内直接引用局部变量本质是一种隐式传参,编译时会自动将引用的局部变量放到参数列表中(Lambda方法多了个参数),而引用的实例变量并不需要放到参数列表,因为方法内可以直接引用。
  • 局部变量有一个特点, 存在于局部变量表中,属于线程私有不共享。随着作用域的结束,可能会被内存回收。 lambda是匿名内部类,如果和主线程运行时使用了不同的线程,那么很有可能在主线程结束后, 局部变量已经销毁,或者发生了更改,那么就会导致实际使用和真实的是不一致的。我理解正因为如此, 实例变量或者静态变量存放在堆中,线程共享, 因此不受这个限制.
  • 造成直接引用的局部变量需要final修饰的原因应该和这种隐式传参有关,在方法传参时,本质上是将实际对象的内存地址赋值给方法参数中的引用变量。所以在Lambda中对参数重新赋值或者在方法中将局部变量重新赋值,对另一方都是没有影响的。

为了避免这种情况的发生,Java 要求 Lambda 表达式中引用的局部变量必须是 final 或 effectively final。这意味着一旦变量被赋值后,就不能再改变其值。这样,Lambda 表达式就可以安全地引用变量的副本,而不必担心副本和原始变量之间的值不一致。

需要注意的是,如果你在 Lambda 表达式中引用的变量是一个对象,那么变量本身的状态仍然可以改变,只是不能将其重新赋值为另一个对象。例如,如果你在 Lambda 表达式中引用了一个 ArrayList 对象,那么你仍然可以向该对象中添加或删除元素,但是不能将其重新赋值为另一个 ArrayList 对象。

为了避免这种误导混淆,保证局部变量和Lambda的变量副本的数据一致性,Java直接在语法层面强制Lambda表达式引用的局部变量不可被重新赋值。

总之,Lambda 表达式中要求局部变量是 final 或 effectively final,是为了确保代码的可读性和一致性。这个限制可以帮助你避免潜在的错误和不一致的行为,同时也可以使代码更加简洁和易读。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值