目录
局部内部类和匿名内部类是什么
局部内部类
匿名内部类
为什么局部内部类和匿名内部类只能访问final的局部变量?
局部内部类和匿名内部类是什么
局部内部类类似于局部变量,声明周期就是定义它的代码块的生命周期,例如在方法中定义,声明周期就是和方法相同,在for循环或者if语句中定义就是和for循环和if语句的生命周期相同
public class Test04 { public void run(){ //局部内部类 class In{ public void Print(){ System.out.println("局部内部类"); } } } }
class Test004{ public static void main(String[] args) { //用lambda表达式创建的匿名内部类 new Thread(()->{ //自动识别到run方法,因为参数Runnable是函数式接口 System.out.println("匿名内部类"); }); //普通的匿名内部类 new Thread(new Runnable() { //重写Runnable方法 @Override public void run() { System.out.println("匿名内部类"); } }); } }
为什么局部内部类和匿名内部类只能访问final的局部变量?
根本原因就是作用于中变量的生命周期导致的
因为我们知道,内部类和外部类是处于同一级别的,内部类不会随着定义在代码块中就随着代码块消亡
在javac命令中,这个类会被创建出两个class文件,一个是外部类Test04的.class文件,一个是Test04$1In.class文件
具体可以看这个例子
public class Test04 { public void run(int a){ //局部内部类 class In{ public void Print(){ a=5; System.out.println("局部内部类"+a); } } In in = new In(); in.Print(); } public static void main(String[] args) { Test04 test04 = new Test04(); test04.run(10); } }
这里就会产生问题:
当外部类代码块(方法)结束时,局部变量(形参)就被销毁了,但是内部类对象可能存在,这里就出现了一个矛盾:
内部类访问了一个不存在的变量!
为了解决这个矛盾,就将局部变量复制了一份作为内部类的成员变量,这样局部变量消亡后,内部类依然可以访问他,实际访问的是局部变量的copy
问题又出现了:
将局部变量赋值为内部类的成员变量时,必须保证这两个变量是一样的,也就是说我们在内部类中修改了成员变量,方法中的局部变量也得跟着改变,怎么解决这个问题呢?
所以就会有将局部变量设置为final的这种办法,让这个变量在初始化后不能再被改变,就可以保证内部类的成员变量和局部变量的一致性,这其实是一种妥协
但是我们发现,如果局部变量不加final,程序也能够成功运行
是因为jdk1.8开始,局部变量如果没有用final修饰,但是你没有在局部内部类中改变其值则也是可以编译通过的。
自己虽然没有定义final,但是jdk1.8在编译生成class文件后会自动给你生成final关键字,也就相当于增加了final
a的值还是无法修改的
参考文章
内部类详解————局部内部类_Morty的技术乐园-CSDN博客_局部内部类
为什么局部内部类和匿名内部类只能访问final的局部变量?_sf_climber的博客-CSDN博客_为什么局部内部类只能访问final
膜拜!华为大牛透彻讲解Java面试100道必考题,不管你工作几年,都得看看!现在免费分享给大家!_哔哩哔哩_bilibili