Java final关键字的作用

目录

前言

一、final关键字是什么?

二、finally是什么

三、finalize简介

 1. finalize定义

2. finalize的执行过程(生命周期)

总结



前言

在面试的过程中经常会被问到:final、finally与finalize的区别,本篇就是为了解释一下此问题。


一、final关键字是什么?

  • 1、final可以用来修饰的结构:类、方法、变量

  • 2、final用来修饰一个类:此类不能被其它类继承。当我们需要让一个类永远不被继承,此时就可以用final修饰,但要注意:final类中所有的成员方法都会隐式的定义为final方法

    • 比如:String类、System类、StringBuffer类

  • 3、final  用来修饰方法  :表明此方法不可以被重写 

    • 作用​​​​

      (1) 把方法锁定,以防止继承类对其进行更改。

      (2) 效率,在早期的java版本中,会将final方法转为内嵌调用。但若方法过于庞大,可能在性能上不会有多大提升。因此在最近版本中,不需要final方法进行这些优化了。

      final方法意味着“最后的、最终的”含义,即此方法不能被重写。

    • 比如:Object类中的getClass( )

  • 4、final 用来修饰变量 ,此时变量就相当于常量

    • final用来修饰属性:可以考虑赋值的位置有:显式初始化、代码块中初始化、构造器中初始化

    • final修饰局部变量:尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参,一旦赋值之后,就只能在方法体内使用此形参的值,不能重新进行赋值。

    • 如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了或者说他的地址不能发生变化了(因为引用的值是一个地址,final要求值,即地址的值不发生变化),但该引用所指向的对象的内容是可以发生变化的。本质上是一回事。

  • 5、static  final  用来修饰属性:属于类的资源-全局变量,static就是类在被加载进内存的时候(也就是应用程序启动的时候)就要已经为此属性分配了内存,所以此时属性已经存在,它又被final修饰,所以必须在属性定义了以后就给其初始化值。

    • 而构造函数是在当类被实例化的时候才会执行,所以用构造函数,这时候这个属性没有被初始化,程序就会报错。

    • 而static块是类被加载的时候执行,且只执行这一次,所以在static块中可以被初始化。

二、finally是什么

异常处理机制:try ——>catch ——>finally(在方法中)

异常的处理:抓抛模型。

说明:

  • 1、finally是可选的,

  • 2、使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应一个异常类的对象。

  • 一旦try中

  • catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下没有关系。

    • catch中的异常类型如果满足子父类关系,则要求子类一定要声明在父类的上面,否则,报错、

  • 常用的异常对象的处理方式:

    • String getMessage() 

    • printStackTrace()

  • 常用的异常对象处理的方式,再出了try结构以后,就不能再被调用。

  • try—catch是可以嵌套的。

finally的使用:一定会被执行的代码:

  • 可以不写

  • 即使catch 中又出现异常了,try中有return语句,catch中有return语句等情况。

  • finally使用的场景:

    • 数据库连接

    • 输入输出流

    • 网络编程Socket等资源,JVM是不能自动的回收的。我们需要手动的进行资源释放。此时就需要放在finally中

三、finalize简介

 1. finalize定义

        finalize()是在java.lang.Object里定义的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法。也就是说每一个对象都有这么个方法。

        这个方法在GC启动,该对象被回收的时候被调用。其实GC可以回收大部分的对象(凡是new出来的对象,GC都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要程序员去实现finalize的。 
特殊情况下,需要程序员实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。 
  使用finalize还需要注意一个事,调用super.finalize();

  一个对象的finalize()方法只会被调用一次,而且finalize()被调用不意味着GC会立即回收该对象,所以有可能调用finalize()后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用finalize(),产生问题。 所以,推荐不要使用finalize()方法,它跟析构函数不一样。

2. finalize的执行过程(生命周期)

(1) 首先,描述finalize大致流程:当对象变成(GC Roots)不可达时,GC会判断该对象是否覆盖了finalize方法,若未覆盖,则直接将其回收。

        否则,若对象未执行过finalize方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize方法。

        执行finalize方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收,否则,对象“复活”。

(2) 具体的finalize

   

各状态含义如下:

unfinalized:新建对象会先进入此状态,GC并未准备执行其finalize方法,因为该对象是可达的

finalizable:表示GC可对该对象执行finalize方法,GC已检测到该对象不可达。正如前面所述,GC通过F-Queue队列和一专用线程完成finalize的执行

finalized:表示GC已经对该对象执行过finalize方法

reachable:表示GC Roots引用可达

finalizer-reachable(f-reachable):表示不是reachable,但可通过某个finalizable对象可达

unreachable:对象不可通过上面两种途径可达


总结

        由此看来,三者除了都包含 final 这几个字符之外,没有特定的深入的联系,只需要讲一下三者的使用场景即可。

  • 11
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值