之前写过一篇文章:从垃圾回收机制解析为什么局部内部类只能访问final修饰的局部变量以及为什么加final能解决问题,经过这两天的学习,发现有些不对,必须再来捋一捋

先看之前的例子:

/**
* @author dmz
* @date Create in 22:28 2019/5/19
*/
public class Test {
public void test() {
String i = "10";
A a = new A() {
@Override
public void test() {
System.out.println(i);
}
};
}
}
interface A { void test(); }

之前我还在Eclipse的时候这段代码明明是报错的,就像这样:

明明会提醒一定要申明为final,不知道为什么到了idea上就不会了

不过这都不是很重要,不影响我们今天的分析。

我们今天直接编译下上面的java文件:

javac Test.java

javac编译一下,得到下面两个文件,我都直接用idea打开了:

// 内部类字节码文件
class Test$1 implements A {
Test$1(Test var1, String var2) {
this.this$0 = var1;
this.val$i = var2;
} public void test() {
System.out.println(this.val$i);
}
}
// 从上面我们可以看到,内部类对象默认持有外部类对象的引用
// 并且还持有外部类定义的变量的引用或者说是值
// 外部类字节码文件
public class Test {
public Test() {
} public void test() {
// 可以看到在编译的时候,默认加上了final关键字
final String var1 = "10";
A var10000 = new A() {
public void test() {
System.out.println(var1);
}
};
}
}

那么现在问题来了,为什么编译的时候,默认会加上final呢?

这样有什么必要吗?

我们知道final主要作用就是:

  1. 对于基本数据类型,保证值不可变
  2. 对于引用数据类型,保证引用不可变

那么现在问题就变成了,为什么局部内部类中引用的外部数据必须要”不可变“呢?

其实这也是一种折衷的实现,究其原因还是因为局部内部类的生命周期跟方法中定义的数据生命周期不一致导致的,这点我在之前的文章里也说过了。

那么为什么加final能解决生命周期不一致的问题呢?

这就要看看我们之前编译后的class文件了,局部内部类其实是复制了一份方法内的数据的引用到自身的属性上。

如果这个引用是final的话,就代表了它不可变,那么局部内部类在复制的过程中,风险是否就缩小了呢?

比如,虽然我跟你生命周期不一样,但是我知道你一定是“10”这个字符串,你不会发生改变,那么即使你死亡了,

那么即使你这个引用死亡了,也并不影响我。大家说,是不是这么个道理呢?

最新文章

  1. 原创 C++作用域 (二)
  2. SSH整合,必出精品
  3. 【系统移植】kernel分析
  4. 后盾网VIP美团网开发(基于HDPHP)(全套38课)
  5. 搭建你的第一个Django应用程序
  6. RNN 与 LSTM 的应用
  7. sql 无法识别的配置节 system.serviceModel
  8. 02_setter注入
  9. Qt学习之路: 国际化(上)
  10. IOS 获取手机各种信息
  11. SQL Server ansi_null_default | ansi_null_dflt_on
  12. java ResultSet 结果集处理 createStatement() 里参数的意义(第一弹)
  13. PHP HTTP 函数
  14. 深入学习Redis:Redis内存模型
  15. 第21月第7日 数据结构 b+树
  16. 【Go语言】基本的语法
  17. springboot启动配置原理之二(运行run方法)
  18. aptana怎么显示空格 tab和回车等
  19. java连接数据库以及连接参数格式
  20. np.stack() 与 tf.stack() 的简单理解

热门文章

  1. SVG案例:动态去创建元素createElementNS
  2. Tcxgrid使用例子
  3. 【特征检测】BRISK特征提取算法
  4. vue2.x学习笔记(三)
  5. element动态添加表头的正确姿势
  6. CVE-2019-1388:Windows UAC 本地提权复现
  7. C#栈、堆的理解(2)
  8. mysql 更改默认字符集
  9. 干货!Python中字符串、列表、元祖、字典,集合之间的转换
  10. Python之小型信息管理系统