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 也一定程度迎合了这一特点。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律