我们都知道实例变量是储存在堆上面的,是线程贡献的。而局部变量则是保存在栈上的,是线程不共享的。
java 访问局部变量的时候,实际上是去访问他的副本。如果局部变量改变了,那访问的也是之前的值。尤其是当 Lambda 是在一个线程中使用变量的,造成的数据不同步问题更加明显,因此 Lambda 有了 final 限制。
在 Java 中方法调用是值传递的,所以在 lambda 表达式中对变量的操作都是基于原变量的副本,不会影响到原变量的值。
综上,假定没有要求 lambda 表达式外部变量为 final 修饰,那么开发者会误以为外部变量的值能够在 lambda 表达式中被改变,而这实际是不可能的,所以要求外部变量为 final 是在编译期以强制手段确保用户不会在 lambda 表达式中做修改原变量值的操作。
另外,对 lambda 表达式的支持是拥抱函数式编程,而函数式编程本身不应为函数引入状态的,从这个角度看,外部变量为 final 也一定程度迎合了这一特点。