Java 中使用 Lambda 为什么只能使用 final 变量?

  • Lambda 表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。
  • Lambda 表达式免去了使用匿名方法的麻烦,并且给予 Java 简单但是强大的函数化的编程能力。

Lambda 原理

很多人提到 Lambda 的原因,就直接说 Lambda 是靠匿名内部类实现的。这个说法不完全准确。

Lambda 表达式,有可能会生成内部类;也有可能会生成私有静态方法,还有可能生成私有方法。

具体是哪种形式,和你使用的函数式编程有关。

关于这个原理,我认为可以单独拿一篇文章来说,今天不过多讨论。

Lambda 变量作用域

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



 

 

上面代码中有一个 num 变量,并没有标记为 final。但是它却被 Lambda 表达式使用了。所以,是你说的不对?

我说的并没有错,原因是,在 Java 中:如果我声明了一个变量,且在后面不更改它的值,那么那就是事实上的 final。这种变量在 lambda 是可以使用的,但是不能被修改。

如果我们尝试修改 num 变量,发现不被允许。


 

 如果我们不在 Lambda 中修改它,而只在 Lambda 中使用它。然后,在 Lambda 外部修改它,可能会有并发问题。正常情况下是允许的,但是在线程中是不被允许的。

我们都知道实例变量是储存在堆上面的,是线程贡献的。而局部变量则是保存在栈上的,是线程不共享的。

java 访问局部变量的时候,实际上是去访问他的副本。如果局部变量改变了,那访问的也是之前的值。尤其是当 Lambda 是在一个线程中使用变量的,造成的数据不同步问题更加明显,因此 Lambda 有了 final 限制。

在 Java 中方法调用是值传递的,所以在 lambda 表达式中对变量的操作都是基于原变量的副本,不会影响到原变量的值。

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

另外,对 lambda 表达式的支持是拥抱函数式编程,而函数式编程本身不应为函数引入状态的,从这个角度看,外部变量为 final 也一定程度迎合了这一特点。



说白,lamda就是内部类的简写,调用外部类变量,必须是final类型的。
posted @   lamda表达式先驱  阅读(1535)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示