final,finally,finalize笔记

354 阅读3分钟

三个完全没有关联的东东,经常被一起提起,总结一下,格式很糟,大家凑合看吧。

一,final修饰的变量不可被修改,修饰方法不可被重写,修饰类不可被继承

修饰成员变量时,变量可以有初始化值,也可以没有初始化值(需要在构造方法中赋值)

有初始化值时,会被编译器优化,直接在使用变量的地方替换为值,所以不可被修改,但如果是复合类型,可以修改复合对象中的属性值

没初始化值时,可以使用反射的方式来动态改变final变量的值

接口中的成员变量,默认修饰符是public static final

另,在局部内部类和匿名内部类中,如果有用到外部方法的局部变量或形参,则需要用final来修饰变量,至于原因,简单来说为了解决方法和内部类的生命周期不一致问题,内部类中所用的变量实际上是外部局部变量或形参的副本,而副本之间会有数据不一致问题,所以需要final来禁止修改,具体细节:www.cnblogs.com/dolphin0520…

二,finally,是Java异常处理的关键字,跟try catch一起使用,三个关键字是有执行顺序的,无论是否发生异常,finally均会执行,可以用于资源的释放等等

finaly在一些极端情况是无法执行的,如在try之前结束方法,在try或catch中执行system.exit结束虚拟机,杀死当前线程,设备断电等等

如果在try和catch中有控制转移语句(return,break,continue,throw),那么finally会被提前执行,然后再执行最后一个控制转移语句(无论这个控制转移语句是在try catch甚至另外一个方法中),具体原理是subroutine,在代码编译时,会把finally中的代码插入控制转移语句之前(注意,是在控制转移语句这一行之前),在执行时,对于return和throw有返回值的控制转移语句,会在执行插入代码之前,保存返回变量到局部变量表中,在return或throw时再把变量返回到操作数栈,因此finally中修改返回变量是无效的(注意,如果return在finally中有效)

大牛博客:www.ibm.com/developerwo…

三,finalize()是Object类中的方法,在Java9中已经被标记为@Deprecated了

它的具体执行过程是:在GC时,如果一个对象不在GC Roots链上了,GC会检查该对象是否有重写finalize()方法,如果没有,那么直接回收该对象,如果有重写,那么把对象加入F-Queue队列,GC会启动一个低优先级线程来处理,在finalize()方法执行完之后,GC会再次判断对象是否在GC Roots链上,如果没有,那么回收对象,如果有,则对象复活。

由上可知,虚拟机并不保证finalize()方法一定会被执行,资源释放操作迟迟得不到运行,且重写了finalize()方法的对象,至少需要两次GC才会被回收,影响程序性能,这也就导致了它的最终被废除,如果在对象被回收时,特别需要及时释放一些资源的话,可以使用虚引用包装对象,并监控引用队列的方式来解决, 具体细节:mp.weixin.qq.com/s/gA7nZtmvg…