一.业务需求重现
上次的开发中,我遇到了这么个问题,因为在业务中会出现重复调用一个变量两次的情况,但需要对其进行不同的数据处理,因为在这种情况下我决定采用初始化对象的方式进行变量的修改,为了保证数据清洗而不影响另外对象的结果集。但此时引发了一个小问题,在开发环境中所需要进行逻辑处理的变量是在lambda表达式中所引用的外部变量,而对于外部变量,lambda中有过明确规定需要对其赋予final的属性,但如果赋予final之后便会产生无法修改指定变量数据的情况发生,这样便形成了自相矛盾的情况(因为我需要既可以进行修改变量又要保证在lambda中是合法操作的),所以便进行final赋值的同时我把它作为数组形式进行索引0的替换操作去创建,这才解决了自相矛盾的问题,那么接下来我来解释一下为什么会产生lambda表达式引用的外部变量必须为final的问题(业务代码因为工作的原因就不方便透露了)。
二.原理解析
因为在jvm中的数据运行时区里有个栈的说法,他会每一个方法去创建一个栈帧,在栈帧中包括局部变量表,操作数栈,动态链接和方法出口,而变量值则是存储在局部变量表中的,而lambda作为一个匿名内部类的形式会在另一个线程中进行运行,同时栈区域也会在它创建的时候为其创建一个栈帧来存储内部变量,而在栈帧之间局部变量表是共享的存在(因为它是通过变量的浅拷贝机制),所以为了防止在lambda线程执行的时候上一个线程把其值进行了修改,此时便可以为其赋予final的属性来让程序正常运行(当然,如果不在lambda的表达式里便可以不需要final啦),希望如果有什么优化的方式可以提点一下,毕竟频繁调用程序,而造成不加节制的new对象会造成堆内存溢出。