• lamda表达式实际上一个匿名内部类
  • 所以我们的问题可以转向这两个问题:
    • 为什么匿名内部类调用外部引用的时候,外部引用需要用final修饰?
    • lamda如果才能修改外部引用变量?

1. 为什么匿名内部类调用外部引用的时候,外部引用需要用final修饰?

  • 我们在内部类中调用外部的自由变量,即使该变量没有显式的声明final,但是在编译器解析的时候也被定义成一个final变量
  • 这里java内部类引用外部变量近似闭包的概念。我们先来了解一下js中满足闭包的条件:
    1. 一个依赖于外部环境自由变量的函数
    2. 这个函数能够访问外部环境里的自由变量
  • 闭包常见使用场景
    1. 回调函数
    2. 匿名函数
  • 在闭包中访问外部自由变量访问的是自由变量的哪个值呢?
    • 是闭包定义时,自由变量所定义的值(非运行时!)
  • js中通常我们要解决闭包导致对象不正确问题,常用的有四个解决方案:
    1. func.call(obj, 20, 30)
    2. func.apply(obj, [20,30])
    3. const func1 = func.bind(obj,20,30)
    4. 在闭包外方法中手动指定 let self = this
  • 说到闭包,绕不开this指向问题,this应该指向的是运行时的对象,简单总结this指向三种情况:
    1. obj.func() -> this指向.前面调用的对象,此时指向obj
    2. new Fun() -> this指向new出来的对象
    3. 函数自调、匿名函数和回调函数 -> this指向的是window
  • java对闭包的处理
    1. 如函数在使用类的全局变量的时候

      • 全局变量实际是类的一个属性,用this指向,可所以修改
    2. 但是在处理匿名内部类的时候,在不同的类中无法用this指向,这时java的做法是:
      • 将自由变量拷贝一个副本带给匿名内部类,供内部类使用。
      • 类似于值传递而非引用传递

2. lamda如果才能修改外部引用变量?

  1. 数组
  2. 全局变量
  3. atomicReference

3. 划重点

lamda不能修改外部引用的变量的原因其实也很简单,本质上就是因为lambda表达式在方法内部,那么lambda表达式的内存分配就是在栈上。栈内存不存在线程安全问题,因为栈内存存的都是变量的副本。
对于局部变量count而言,它的生命周期就是所在方法的生命周期。这就决定了count无法被位于同一个栈帧上的lambda修改,因为这种修改毫无意义,
你无法将你的修改传递出当前栈帧。栈内存不会被共享,也就意味着你没有权利和其他栈帧通信。如果非要在lambda内部修改lambda表达式外部的局部变量的值呢?
有两种方式:使用数组或者把局部变量定义为全局变量。这2种方式,其实本质是一样的:内存都分配在堆上。这就决定了,使用这2种方式来修改变量的值,是可行的。

转载请注明出处:www.meidanlong

为什么lamda不能修改外部引用的变量?相关推荐

  1. win7 64位 安装java jdk1.8 ,修改配置环境变量

    下载jdk1.8,下载地址:http://www.wmzhe.com/soft-30118.html 安装时有两个程序,都安装在同一个目录下.   win7 64位 安装java jdk1.8 ,修改 ...

  2. windows下安装composer方法(不修改PATH环境变量)

    转载地址:http://www.th7.cn/Program/php/201410/297829.shtml composer是一个新崛起的PHP的依赖管理工具.官方安装方法见: https://ge ...

  3. linux unset path,linux查看和修改PATH环境变量的方法

    查看PATH:echo $PATH 使用env命令显示所有的环境变量: $ env 使用set命令显示所有本地定义的Shell变量: $ set 使用unset命令来清除环境变量 set可以设置某个环 ...

  4. Ubuntu进入pycharm创建的虚拟环境的方法(以及如果你安装了anaconda等其它修改了环境变量的东西该怎么进)

    我们的服务器同时存在anaconda和原生的python,这样导致了一个特别坑的问题. anaconda修改了环境变量(进入~/.bashrc并没有找到),但是我们却找不到它修改的是哪里,导致常规进入 ...

  5. String为什么无法在方法中修改原有string变量的值

    题目 public class Exam10{ String str=new String("good"); char[]ch={'a','b','c'}; public stat ...

  6. 修改jdk环境变量后,在cmd中看版本没有变化

    问题描述: 修改jdk环境变量后,在cmd中看版本没有变化 解决方案: 把环境变量配置的系统变量部分中的Path部分中jdk配置移到该配置最前面.

  7. Linux下修改PATH环境变量

    Linux下有很多环境变量,PATH就是其中的一种 PATH 可执行文件的搜索路径.ls命令也是一个程序,执行它不需要提供完整的路径名/bin/ls,然 而通常我们执行当前目录下的程序a.out却需要 ...

  8. 5 修改request对象变量_【总结】前端5大常见设计模式,代码一看你就懂!

    前言 今天主要介绍一下我们平常会经常用到的设计模式,设计模式总的来说有23种,而设计模式在前端中又该怎么运用呢,接下来主要对比较前端中常见的设计模式做一个介绍. 设计模式的定义 设计模式是在面向对象软 ...

  9. python 类变量修改_python中类变量与成员变量的使用注意点总结

    前言 最近在用python写一个项目,发现一个很恶心的bug,就是同由一个类生成的两个实例之间的数据竟然会相互影响,这让我非常不解.后来联想到java的类有类变量也有实例变量,因此翻阅了相关资料,发现 ...

最新文章

  1. 微生物组—宏基因组分析专题培训开课啦!10月北京
  2. 剑指offer:左旋转字符串
  3. php自动生成新闻页,自动发布新闻页面的php代码
  4. Android-FixBug热修复框架的使用及源码分析(不发版修复bug)
  5. 开发们 点广告-赚点BT币
  6. 您真的理解了SQLSERVER的日志链了吗?
  7. 修改centos6.3启动级别以及启动级别配置错误的修改问题
  8. Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - MMX技术(1) - 概述 传输指令
  9. gc:C语言的垃圾回收库-英文
  10. 罗翔 ---- 理想主义的花
  11. “支付功能”怎么测试?
  12. 《TCP/IP路由技术(第二卷)》一1.6 附 注
  13. 服务器装系统蓝屏怎么办,重装系统蓝屏怎么办
  14. java调用公安接口_src 公安部PGIS在交警系统的应用,包括 的各种API 以及mysql对空间数据的支持 GIS program 261万源代码下载- www.pudn.com...
  15. 【Word】word2010中如何去掉标题前面的小黑点
  16. sonar代码质量分析
  17. 一种基于SoC和阿里云的智能家居系统设计方案_家电研究报告
  18. 论文笔记——HDD算法:异构网络中信息扩散的深度学习方法
  19. 柱状图python_化学领域里「过柱子」是什么意思?柱子干了为什么可怕?
  20. 入门学习Linux常用必会命令实例详解

热门文章

  1. 朴素贝叶斯方法(Naive Bayes)原理和实现
  2. mysql insert锁机制
  3. 十大经典数据挖掘算法:EM
  4. 【机器学习】今天想跟大家聊聊SVM
  5. 一次CMS GC问题排查过程(理解原理+读懂GC日志)
  6. AJPFX关于构造器的总结
  7. Eclipse+PyDev+Django+Mysql搭建Python web开发环境
  8. 细细品味C#——文件操作
  9. 一、从零创建VUE项目
  10. pyqt5实现注册界面并获得文本框内容