public class LambdaTest {public static void main(String ... args){int portNumber = 1337;Runnable r = ()-> {portNumber = 1338;System.out.println(portNumber);};r.run();}
}

如上代码,lambda里面要访问局部变量会报如照片错误:

在介绍为什么会报错的原因之前,稍作先介绍什么Lambda表达式

一、什么是lambda表达式

在java8实战这本书中,将Lambda表达式解释为:可传递的匿名函数的一种方式:它没有名称,但他有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表

二、在哪里使用Lambda表达式

1.函数式接口:只定义了一个抽象方法的接口
2.函数描述符:函数式接口的抽象方法的签名基本上就是Lambda表达式的签名,这个抽象方法叫做函数描述符

三、函数式接口可以干什么?

lambda表达式可以以内联的形式为接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例即创建一个函数式接口的实例

四、为什么lambda里面要访问局部变量必须是final

现在再来解释为什么lambda里面要访问局部变量必须是final?

首先:lambda表示可以无限制捕获实例变量(即表达式主体中的引用)和静态变量

但是,局部变量必须是显示声明为final或事实上是final

那么这lambda里面要赋值局部变量必须是final有什么关系?

实例变量:存储在堆中

局部变量:则保存在栈上

lambda表达式以内联的形式创建一个函数式接口的实例,保存在堆中,而局部变量则保存在栈中,可能造成实例对象得生命周期很有可能超过局部变量得生命周期:

1.局部变量声明周期:当该方法被调用时,该方法中的局部变量在栈中被创建。当方法调用结束时,退栈,这些局部变量全部死亡。而函数式接口实例对象生命周期和其他类对象一样:自创建一个实例对象,系统为该对象分配内存,直到没有引用变量指向分配给该对象得内存,它被JVM垃圾回收,所以完全可能出现的一种情况是:方法已调用结束,局部变量已死亡,但实例对象的对象仍然活着。

2.如果实例对象访问了同一个方法中得局部变量,就要求只要实例对象还活着,那么栈中的那些它要所访问的局部变量就不能死亡

因为创建一个函数式接口实例实际也是创建一个匿名内部类,这里是从匿名内部类的角度分析

以下是《java8实战》解释:

1.Lambda可以直接访问局部变量,而且Lambda是在一个线程中使用的,则使用Lambda的线程,可能会在分配该变量的线程将这个变量收回之后,去访问该变量。因此,Java在访问自由局部变量时,实际上是在访问它的副本,而不是访问原始变量。

2.这一限制不鼓励你使用改变外部变量的典型命令式编程模式

五、lambda里面要赋值局部变量而不使用final

则局部变量使用=》引用类型

属于个人理解,有不对的地方也请指出。

lambda里面赋值局部变量必须是final原因相关推荐

  1. java lambda 局部变量_java Lambda表达式访问局部变量详细介绍

    此前给大家带来了java Lambda表达式访问成员变量详细介绍,下面就要继续给大家介绍java Lambda表达式访问局部变量的内容,一起通过简单的文章来进行了解吧. 对于成员变量的访问Lambda ...

  2. java nextintln_java – 从lambda表达式引用的局部变量必须是final或者有效的final

    我有一个JavaFX 8程序(适用于JavaFXPorts交叉平台),它实际上是为了做我想做的事情,但却是一步之遥.程序读取文本文件,对行进行计数以建立随机范围,从该范围中选取一个随机数并读取该行以进 ...

  3. 匿名内部类和局部内部类访问的外部类的局部变量必须是final的

    从java8开始,如果一个外部类的局部变量被匿名内部类访问了,那么系统会自动为该变量加上一个final修饰符,则该变量就不能被重复赋值了. 可参考下面链接中,步骤5处的解释: http://how2j ...

  4. 局部内部类访问它所在方法中的局部变量必须是final

    https://www.cnblogs.com/oldpub-blog/p/9026824.html https://blog.csdn.net/whuslei/article/details/625 ...

  5. 局部内部类访问方法中的局部变量为什么加final

    1)从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变量(形式参数或局部变量)是天经地义的.是很自然的 ...

  6. java实例变量,局部变量,类变量和final变量

    题目 答案:B 解析 实例变量: 定义在类中的变量是类的成员变量,可以不进行初始化, java 会自动进行初始化.(如果是引用类默认初始化为 null, 如果是基本类型,默认初始化为 0 ) 局部变量 ...

  7. java final成员变量吗_阳光沙滩博客-为什么Java匿名内部内使用局部变量需要加final?而访问成员变量却不用加final呢?...

    前置知识 内存数据区域(Java内存结构) 在解析这个问题之前,得先有一些前置知识. 比如说,要知道什么是堆,什么是栈,什么是方法区,这数据区域存放什么内容? 可以参考这篇文章: 栈里面存放方法内容 ...

  8. 为什么局部内部类访问外边的局部变量必须为final?

    6.局部内部类访问外边的局部变量时,此变量必须为final类型  由于技术方面的限制,java的设计者们做出如下语法规定:局部内部类访问外边的局部变量时,此变量必须为final类型,(为什么请参考我的 ...

  9. 栈2——局部变量要初始化的原因

    同一个线程的所有函数共享同一个栈地址空间,上个函数用完这个栈,系统并没有把这个栈清0,下个函数的局部变量压栈用的还是同一个栈地址空间,那么这个局部变量不初始化就用的话,其值是上个函数的遗留值,但因为数 ...

最新文章

  1. springboot的jsp应该放在哪_web项目jsp放在哪里 Spring Boot 静态资源处理(4)
  2. 后处理编辑修改_NX后处理打开报错处理方法
  3. php文件在桌面删除不了图片吗,删除windows桌面上某个应用程序的图标,意味着什么...
  4. java 用于xcopy复制_java调用copy复制子文件夹及文件到指定目录(非xcopy)
  5. Ubuntu18.04上安装RTX 2080Ti显卡驱动
  6. SQL Server Profiler使用方法
  7. IoC(控制反转)的主要组件和注入的两种方式
  8. Visual Studio 2019 16.3 Preview 3 发布,使用 IntelliCode 重构更容易
  9. Occluded Pedestrian Detection Through Guided Attention in CNNs 论文总结
  10. python局域网控制电脑关机_黑客操作:用python远程开机and关机
  11. 公司买网络设备,至少16口
  12. 球球大作战代点链接源码c语言,最新球球大作战代点源码无加密开源-球球大作战一天刷100个棒棒糖和刷龙蛋200个源码下载免费版-西西软件下载...
  13. 纯前端表格控件SpreadJS——轻松搞定数据绑定
  14. 回声消除原理(AEC)
  15. 16进制颜色码对照表
  16. pmp采购管理--合同类型
  17. Spring boot2.0 JpaRepository findOne的使用
  18. 使用Nginx Upstream 部署 OpenERP
  19. 基于matlab分析的商业保险案例
  20. 基础理论知识复习(上)

热门文章

  1. php ci框架 实例化类,php框架CI(codeigniter)自动加载与自主创建对象操作实例分析...
  2. [转载] 【python魔术方法】迭代器(__iter__和__next__)
  3. Python程序查找表示O(1)复杂度的数字所需的位数
  4. scala中def_def关键字以及Scala中的示例
  5. express rest_Express / Node中用于REST API的邮递员工具
  6. 最小生成树 kruskal_使用Kruskal算法求解Java最小生成树问题
  7. android 百度地图api密钥,Android百度地图开发获取秘钥之SHA1
  8. micropython移植教程_【教程】智能编程T-Watch手表初试micropython之电子秤教程
  9. python radians函数_Python3 radians() 函数
  10. 双向tvs和单向tvs_TVS的完整形式是什么?