final,finally,finalize的区别(Android每日面试题)

1,402 阅读5分钟

前言

看见即降服,这句话说的是一件事物,只要你看得到,你就能得到。

对我来说记录就是看见。

面试题不只是为了面试,更是为了帮助我们更深入地理解我们已知的知识。

问题分析

当听到这个问题的时候,有种上学时候那种应试考试的感觉,不知道在坐的各位有没有。因为final,finally,finalize这三个根本没有任何联系,只是长得像而已,仅此而已。这个问题跟重写和重载的有什么区别一样,看起来像是考官为了凑题数才出的题。但是既然有人提出这个问题,那出题人肯定有他自己的出发点,我猜是为了考察我们对这些关键字意思的理解程度。那么接下来我们看一下这三个关键字都是什么意思,有什么作用。

final

首先我们知道,final的中文意思是最终,它在java语言中是一个修饰符,就像pulbicprivate等修饰符一样,ok,我们现在知道了final的作用是修饰。既然是修饰符,那它能修饰什么呢?答案是非抽象类非抽象方法变量。下面我们分开来讨论下。

修饰非抽象类

  • 有什么作用/结果/效果

    答:作用就是这个类不能被继承了,因为不能被继承,所以它的所有方法默认都是final(因为被final修饰的方法不可以被子类重写)。

  • 什么时候用

    答:当你设计一个类不需要子类或者不想被别人继承扩展的时候,加上final修饰就行了。例如String(关于Stringfinal设计可以看一下为什么String要设计为final不要问我为什么每篇文章都要用别人文章的引用,问就是我要站在巨人的肩膀上)。

修饰非抽象方法

这个主要是为了不让其子类对重写该方法。还有一个作用是效率(这个作用可以看下文章底部的参考链接)。

修饰变量

final修饰的变量分两种:

  • 修饰基本变量:例如 final int a = 1;;首先要明白基本变量在内存中的存放位置是什么(这个内存的东西可以学习一下JVM那本经典的书),好啦,答案是基本变量存放的位置方法栈。那么final修饰基本变量的时候对基本变量有什么作用呢?答案是,这个基本变量a所指的内存地址(也就是 1所在的内存地址)不能再被修改了。
  • 修饰引用变量:例如 final Person p = new Person();首先我们需要知道引用变量在内存中存放的位置是。同上,这个final的修饰作用是p所指的内存地址不能再被修改了,但是对于引用变量来说,只是内存地址不可以被改变,内存地址中的内容可以改变。

你要问我为什么基本变量的内容不可以变?这个问题。。。好吧,我们如果要改变基本变量a的内容,我们是不是要这么写a = 2;?那首先不说ide会编译不过,即使编译过,我们想一下,java中整数-127-128是默认被加载到常量池里的,那么a = 2;就会导致引用a的指向从1的内存地址变为2的内存地址,这个是不是就和final修饰的变量,变量引用所指的内存地址不可被修改这句话矛盾了?

总结引用下文末文章的一句话:

final修饰变量的本质: final修饰的变量会指向一块固定的内存, 这块内存中的值不能改变.

对于final这个关键字的知识点还有一些深层次的东西,大家可以详细查看文末的链接!

finally

finally这个关键字是和try...catch配合使用,它的作用:

  1. 处理完异常后对资源进行释放

  2. 为什么有上面作用1的效果呢?是因为一般情况下finally的代码块都会执行,非一般情况可以点击第三条的链接详细查看。

  3. finallyreturn遇到时程序会怎么运行,我觉得这些都算是java的细节语法。

finalize

额,首先finalize是一个方法,应该是finalize()。它是Object类中的一个方法。 这个方法的定义是这么说的:

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

翻译如下:当我们内存中的某个对象没有被任何其引用时并且垃圾回收器gc准备回收该对象的时候,finalize()方法将被调用。

那么对于finalize()方法的调用问题可以看一下SO社区(StackOverflow是一个非常好的网站,作为程序员开发的我们不应该忽视这个网站)java中的finalize()方法什么时候会调用?

这个OP(Origin Post)的问题是

我创建了一个类,并在finalize()方法里面执行了文件的写入操作(意思是他想通过文件是否有写入东西来判断finalize()是否被调用),但是这个方法从来都没有被执行。

Vote Up最多的并被接受的一个回答是

大概意思是:请阅读javadoc,finalize()方法可能在程序的一生中都不会被调用,并且垃圾回收器也不保证在某个特定时间会执行。所以除非你有特定需求否则不要依赖finalize()。(好吧,我也不清楚什么才算特定需求,我在开发过程中也没用过这个方法,如果在坐各位谁对该方法有经验,欢迎评论区指出!)

参考

juejin.cn/post/684490…