Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
N
note
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
黄夏豪
note
Commits
28421349
提交
28421349
authored
7月 13, 2020
作者:
邓砥奕
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
第一次添加笔记
上级
c44be931
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
24 行增加
和
0 行删除
+24
-0
Lambda和匿名内部类.md
邓砥奕/Lambda和匿名内部类.md
+24
-0
折线图.png
邓砥奕/折线图.png
+0
-0
雪花算法Snowflake.md
邓砥奕/雪花算法Snowflake.md
+0
-0
没有找到文件。
邓砥奕/Lambda和匿名内部类.md
0 → 100644
浏览文件 @
28421349
## Lambda和匿名内部类
#### 一、引用外部方法局部变量
Java8之前Lambda和匿名内部类引用外部局部变量必须声明为final类型,Java8之后引用的局部变量必须为final或effectively final.如果该局部变量在定义赋值后没有被修改,则认为该变量为effectively final类型,如果被赋值或修改则无法通过编译。因此在引用外部局部变量时,不能进行修改。
#### 二、为什么必须为final或effectively final
1.
由于Lambda和匿名内部类无法直接访问外部局部变量,因此只能通过它们的构造方法将需要引用的局部变量传入进去。通过构造方法传递的只是局部变量的一个拷贝,因此当外部或者内部类修改这个变量时,对方都不知道该变量的修改。为了保证变量的安全,所以在Java中直接不允许修改引用的局部变量,编译时该变量必须为final或者effectively final类型。
2.
局部变量和内部类对象的生命周期不同。当调用该方法时,该方法中的局部变量在栈中被创建,可能该方法调用结束并且释放了栈中的变量,但是内部类却还没有执行完,此时就找不到该局部变量了。为了保证变量的安全访问,内部类会自动通过构造函数的参数创建一个final类型的拷贝值。由于是拷贝值,因此一但一方修改了局部变量的值会导致另外一方对该变量的更改不可见,从而出现问题。
3.
并发的安全性问题。当多个线程并发执行Lambda或匿名内部类中的代码时,不能保证外部成员变量的原子性,从而可能导致变量值的安全性问题。当引用自由变量时,考虑并发的安全性,也必须为final或effectively final。
#### 三、修改变量的一些方法
1.
定义为内部类局部变量
2.
定义为外部类的成员变量:成员变量存储在堆上,可以正常访问。
3.
定义为Atomic原子类型:保证了变量的可见性和原子性。
4.
定义为数组、list:数组和list的地址不会发生改变,可以修改数组和list中的值,但是并发时不能保证安全性。
邓砥奕/折线图.png
0 → 100644
浏览文件 @
28421349
19.7 KB
邓砥奕/雪花算法Snowflake.md
0 → 100644
浏览文件 @
28421349
差异被折叠。
点击展开。
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论