Java - Lambda 和 匿名内部类(ACI)引用局部变量(Local Variable)必须申明为final的原因

如果经常使用lambda表达式,一定会对这个约束感觉非常麻烦,非常费解为何Java有此限制;
网络上大多的文章往往都是分析Java如何去实现匿名内部类,比如是对当前局部变量引用的copy; 但是似乎都没清晰说明必须申明为final的理由;
下面是一些 信息和猜测


  • 这个限制其实是只针对于局部变量(local variable) 而对成员变量(field)并无final限制;这个也很好理解,因为ACI 并没有直接引用field, 而是引用当前的外部对象本身this; 本质而言, 只是限定它直接引用的变量引用不可变
  • 其实想回避上面该问题已经有一种简单的代码范式,叫做手动boxing(JDK源码里自己都在用);如下面代码,简单的用另一个东西封装一下需要被修改的内容,就可绕过这个限制(其实也理解为field是被this封装过,所以可以绕过限制);
        Integer[] ia = new Integer[0];
        
        ia[0] = 31;
        ia[0] = 32;
        
        Integer i = 0;
        
        i = 31;
        i = 32;
        
        Supplier<Integer> s = ()->{
            return ia[0];
            //cannot compile
            return i;
        };
  • 关于引入这个控制的原因。首先技术上我觉得不存在问题,与当前JVM的设计不存在冲突问题,而且在其他类Java的语言里也早已经做到;我见到有许多人回答,可能导致的Sync Problem, 这个也算是个合理的理由。lamdba 表达式时,它的目的不仅仅为了让代码书写更加简练,同样重要的是支持并行计算的特性(也就是多线程)。可能JCP设计时,就默认每个lamdba就必须考虑多线程并发问题;这个约束在我看来并不能解决线程安全的问题,但它可以提醒开发者注意可能的线程安全问题(就像Optional可以强制开发者考虑null exception问题);
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、什么是RF? 答:RF 即Radio frequency 射频,主要包括无线收发信机。 2、手机RF IC处理...
    hades2013阅读 1,611评论 0 2
  • 这是一篇比较沉重的文章,复杂的人不要看,迷茫的人希望对你也有所帮助。 我常常疑惑,明明我的内心活动如此丰富,却表现...
    碎片先生阅读 511评论 0 1
  • 今天天气晴朗,蓝蓝的天空飘着朵朵白云。小红端来一盘清水洗手帕。手帕洗的干干净净的。小猴开心的笑了。
    薛翔少阅读 246评论 0 0
  • 让我的天空灿烂的是亲人们暖若阳光的笑。我爱你们,我的父母姐妹,我的亲友们,你们的笑,是我全部的信仰。 ...
    陈鑫怡123阅读 548评论 0 0
  • 转眼已然是北国的秋。 北方的秋天,是分明的,四季像是刀切的圆饼,干脆,分明,划线清晰。 ...
    山外有凉风阅读 394评论 0 4