logo头像

不破不立

Java关键字之final和finally以及finalize

本文于1224天之前发表,文中内容可能已经过时。

这是Java程序员面试宝典中一道面试题,同时很多公司企业面试的时候也喜欢问这道题,前些天一位学长(斌哥)回来一起聚聚的时候还说自己面试的时候遇到了这道题。现在我们就来讲讲这道题,加深自己的理解。全都是文字性的东西,讲的可能比较乏味,但是应该挺好懂的,不懂的可以一起交流。

final

  想必大家都知道这是Java中定义常量的一个关键字吧;不过它可不止这一个用处啊,下面细细讲来。

1. final+变量v组合,即使用final定义变量v

  解释:变量v一旦被初始化,则不能再被修改了。

  这里的初始化有两个地方,一是定义的时候初始化,二是在构造函数中。二者只能选其一,而且初始化之后便只能读取不能修改了。

  这里的不能被修改对不同的变量有不同的定义。对于基本类型定义的普通变量v来说,是指v的值不能被改变,即就是常量了。对于是类定义的对象变量v来说,是指v的引用不可变。

  针对这一组合还有一种比较特殊的用法,就是在方法的形式参数中使用。这一用法对于基本类型的变量是没有实际意义的,因为Java中的方法调用在传基本类型的参数时是传值调用的;但是对于对象变量很实用,因为Java中的方法调用在传对象时传的是对象的引用,而如果在调用的这个方法体中的某处修改了该对象的引用可能会影响到其他地方使用该对象变量的引用,所以这里就需要用到final定义形式参数对象变量不可变。

2. final+方法m组合,即使用final关键字定义方法m

  为什么要将方法定义为final?我们来看看产生这个组合的需求是什么。

  需求有以下两点:

  1. 认为这个方法提供的功能已经满足了自己的要求,不需要并且不允许通过继承等手段来覆盖重写这个方法,这里是允许继承这个方法直接使用的,但是不允许修改了。
  2. 允许编译器将所有对该方法的调用转换为行内(inline)调用的机制,即是把调用该方法的代码直接转换为该方法的全部代码,而不是通过保存断点、压栈等手段进入到该方法。可以看出这样会使程序免去了方法调用的时间,使得效率提高了一些;但是得注意m的方法体比较小,并且调用该方法的地方不多,只是偶尔使用一下,否则会适得其反。 哈哈,现在应该知道了final+方法的组合的用法了吧。

3. final+类c组合,即是final关键字定义类

  与上述讲方法的有点类似的地方,final定义类是表示此类c被认为设计的很完美了,不需要进行修改或者扩展等。所以final定义的类c是不能被继承的,也说明了final关键字不能和abstract关键字一起使用。对于final类c中的成员变量,可以定义为final,可以不定义;而c中的方法则都是final类型的,不管是否加关键字final。

finally

  这个大家应该经常在try语句中看到吧,相信应该都比较懂它的功能。这里解释一下,在try catch语句块中,后面建议加一个finally块,这样被定义在finally块中的代码(用fcode代称一下),不论try或者catch是否运行,fcode都会在它们(try和catch块)运行之后运行。注意一下这里有个特别的情况,就是如果try或者catch里面有return语句,finally里面的代码块fcode会在return语句执行之前执行。因为一个方法在执行return语句后就会被销毁。 finally它常常用来清理资源,大家应该会在使用jdbc连接数据库的时候用到。

finalize

  它是方法名,大家或许有可能在看垃圾回收的地方看到过,没错,它确实和垃圾回收有一些关系。

  使用finalize()方法在t(代称,后面有解释,便于理解)时之前做出必要的清理工作。这里的t是指垃圾收集器将对象从内存中清除出去。而什么时候调用呢?是在t1时(即在垃圾回收器确定这个对象没有被引用时,决定删除这个对象之前)对这个对象调用的。在Object类中定义的,所有的类都继承了它。

  看到这里应该都对这三个英文单词有比较深的理解了吧,如果还不理解或者发现文中哪里有什么问题的,欢迎在下面留言,大家一起讨论,帮助更多的人!

上一篇