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