- 匿名内部类访问的外部类局部变量为什么要用final 修饰?
- jdk8为啥不需要了?
更多问答 >>
-
每日一问 事件分发机制大家应该都熟记于心,默认事件分发是逆序的,有哪些方法可以修改分发顺序?
2019-08-11 21:18 -
2019-08-12 09:58
-
每日一问 Android 有哪些 位运算 的例子很值得借鉴?
2019-08-13 21:56 -
2019-08-18 21:42
-
每日一问 今天聊一下Gradle 相关,BuildConfig这个类是如何生成的?
2019-08-20 23:27 -
每日一问 AppCompatTextView 与 TextView 1/3
2019-08-07 01:29 -
每日一问 大家应该都有泛型在编译期会被擦除的概念,那么为什么我们在运行时还能读取到呢? 3/3
2019-08-04 19:44 -
2019-08-01 21:44
-
每日一问 很多时候我们说"Android16.6ms刷新一次屏幕" 正确吗?
2019-07-30 21:53
1.因为 匿名内部类 使用的是 外部类局部变量 的值,并非引用
2.jdk8 其实用了语法糖,自动加了final,其实和原来一样先看一下Java对匿名内部类访问外部类局部变量的处理
上面 这段代码编译成两个class文件(一个.java文件中有几个类就会编译出几个.class文件)
匿名内部类是这样的外部类是这样的
可以看到,外部类以及被访问的局部变量会通过构造函数传进去,对于局部变量,内部类使用的引用和外部类使用的并不是同一个,而如果局部变量不是final的话,当其中一方对其重新赋值就会导致内部类和外部类的数据不同步,大概就是像下面这种,结果会输出false,所以要声明成final
关于外部类的全局变量为什么不用声明为final,是因为在内部类中是通过this来访问的,这个和外部类是同一个引用
因为内部类是通过构造参数的方式传入的外部类以及所用参数。
如果不用final会出现什么情况呢:你把变量a传给内部类了,然后对变量a重赋值了,这时候内部类和外部类的a就会出现一个是oldValue一个是newValue。所以为了避免这个情况,就直接final规定,不让你重赋值。为什么8不需要了呢,因为8有自动判断机制,如果你的变量没有发生重赋值,就会自动加final,类似kotlin的自动类型判断(var a=1),但是如果你违背了这种判断机制(发生了重赋值),这个时候就会报错,提示你需要内部类需要一个final修饰的变量