Java关键字final的实现原理分析
作者:user2025
这篇文章主要介绍了Java关键字final的实现原理分析,在JDK8之前,如果在匿名内部类中需要访问局部变量,那么这个局部变量一定是final修饰的,但final关键字可以省略,需要的朋友可以参考下
final的作用
静态方法可以修饰类、静态成员变量、普通成员变量、普通方法、局部变量
(1)final修饰类的作用:阻止当前类被继承
(2)final修饰的方法的作用:阻止子类继承和重写【注意:子类可以重载该方法】
(3)final修饰的成员变量初始化后便不可用修改,基本数据类型不能修改值,引用数据类型实际是引用不能修改修改,但引用指向存储对象空间中的内存可以被修改
final不能修饰抽象类
抽象类是用于被子类继承的,和final修饰类的作用冲突
静态方法没有必要修饰静态方法
静态方法可以修饰静态方法,但没有必要,因为final也无法阻止子类申明相同签名的的静态方法。父类的静态方法可以被子类继承,不能被子类重写,但子类可以申明相同同名的方法,父类的静态方法只是被隐藏了而不是被重写了。
匿名内部类访问方法中的局部变量为什么必须被final修饰
- 在JDK8之前,如果在匿名内部类中需要访问局部变量,那么这个局部变量必须用final修饰符显示修饰;
- 在JDK8之前,如果在匿名内部类中需要访问局部变量,那么这个局部变量一定是final修饰的,但final关键字可以省略
分析final修饰的变量如何传入匿名内部类
public class Demo { public static void main(String[] args) { int a = 10; String b = "abc"; Thread thread = new Thread(() -> { System.out.println(a + b); }); thread.start(); } }
反编译后的关键代码如下:
发现方法中的两个局部变量,作为参数传入了内部类中,事实上最符合反编译代码表述的是:
public class Demo.lambda$main$0 extends Thread { private int a; private String b; Demo.lambda$main$0(int a,String b) { this.a=a; this.b=b; } public void run() { System.out.println( a + b ); } }
final修饰的局部变量是作为匿名内部类构造器的参数传入匿名内部类内部的
为啥需要final修饰局部变量
final修饰局部变量还是防止数据被修改,保证数据的一致性,对引用变量来说是引用地址的一致性,对基本类型来说就是值的一致性。
- 局部变量通过匿名内部类的构造器的参数参入匿名类中,如果是基本数据,实际传递的是值,如果是引用数据类型,实际传递的是引用,匿名内部类中实际是存了局部变量的副本。
- 匿名内部类中和方法中任意一处修改了,另一方都不受影响,这样就会导致数据不一致,从而影响运行结果,所以需要final修饰。【注意:如果是引用数据类型,这里修改是指的引用,如果是修改引用数据类型的成员变量,实际上双方是一致的,修改的是堆内存中的数据,而不是虚拟机栈中的】
到此这篇关于Java关键字final的实现原理分析的文章就介绍到这了,更多相关final的实现原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!