题目:谈谈 final、finally、finalize的区别?
解析:如题,如果要知道他们之间的区别,那么我们必须要知道它们每一个是什么意思。
1 . final
final 可以用于控制成员、方法,或者是一个类是否可以被覆写或继承等功能,这些特点 final 在 Java 中拥有一个不可或缺的地位,也是学习 Java时必须要知道和掌握的关键字之一。
(1)final 成员
当在类中定义变量时,若在其前面加上 final 关键字,那就是说,这个变量一旦被初始化,便是不可改变的。
例如:final String str = "abc";
final int a = 8;
这里的不可改变的意思对基本数据类型(如a的值)来说是其值不可变,而对于对象变量(如引用 str )来说是引用不可变。其初始化可以在两个地方,一是其定义处,二是在构造函数中,二者只能选其一。
还有一种用法是定义方法中的参数为 final 关键字。对于基本数据类型的变量,这样做并没有什么实际的意义,因为基本类型的变量在调用方法时是传值的,也就是说,我可以在方法中更改这个参数变量而不会影响到调用语句,然而对于对象变量,却显得很实用,因为对象变量在传递时是传递其引用的,这样,我在方法中对对象变量的修改也会影响到调用语句中的对象变量。当你在方法中不需要改变作为参数的对象变量时,明确使用 final 进行声明,会防止你无意的修改而影响到调用方法。
(2)final 方法
将方法声明为 final 有两个原因。第一就是说明应知道这个方法提供的功能满足要求,不需要进行扩展,并且也不允许任何从此类继承的类来覆写这个方法,但是仍然可以继承这个方法,也就是说,可以直接使用。第二就是允许编译器将所有对此方法的调用转化为 inline(行内)调用机制,例如,保存断点、压栈等(?),这样可能会使程序的效率有所有提高。然而,当方法的主题非常庞大的时候,或者在多处调用此方法时,调用主体代码便会迅速膨胀,可能反而影响效率,所以要慎用 final 进行方法定义。
(3)final 类
当将 final 用于类时,就需要仔细考虑,因为一个 final 类是无法被任何人继承的,那也就以为着此类在一个继承树中是一个叶子类,并且此类的设计已被人很完美,不需要进行修改或扩展。 对于 final 类中成员,可以定义其为 final,也可以不是 final。 而对于方法,由于所属的类为 final 的关系,自然也就成了 final 型的。也可以明确的给 final 类中的方法加上一个 final ,但这个显然是没有意义的。
2. finally
finally 关键字是对 Java 异常处理模型的最佳补充。finally 结构使代码总会执行,而不管有无异常发生。使用 finally 可以维护对象内部的状态,并可以清理非内存资源。如果没有 finally ,我们的代码就会很费解。
3. finalize
根据 Java 语言规范,JVM保证调用 finalize函数之前,这个对象是不可达的,但是JVM 不保证这个函数一定会被调用。另外,规范还保证 finalize 函数最多运行一次。
通常,finalize 用于一些不容易控制,并且非常重要的资源的释放,例如,一些 I/O 的操作、数据的连接。这些资源的释放对整个应用程序是非常关键的。在这种情况下,程序员应该可以通过程序本身的管理(包括释放)这些资源为主,以 finalize 函数释放资源方式为辅,形成一种双保险的管理机制,而不是应该仅仅依靠 finalize 来释放资源。
答案
1. final 修饰符 (关键字)
如果一个类被声明为 final , 意味着它不能在派生处新的子类,不能作为父类被继承。因此,一个类既不能被声明为 abstract ,又被声明为 final 。将变量或者方法声明为 final,可以保证它们在使用中不被改变。其初始化可以在两个地方:一个是其定义处,也就是说,在 final 变量定义时直接给其赋值;而是在构造函数中。这两个地方只能选其一,要么在定义时给值,要么在构造函数中给值,不能同时既在定义时给了值,又在构造构造函数中给另外的值,而在以后的引用中只能读取,不可修改。被声明为 final 的方法也同样只能使用,不能重写(override)。
2. finally
在异常处理时提供 finally 块来执行任何清楚操作。如果跑出一个异常,那么相匹配的 catch 自居就会执行,然后控制就会进入 finally 块 (如果有的话)。
3.finalize
finalize 是方法名。 Java技术允许使用 finalize() 方法在垃圾收集器将对象从内存清除出去前做必要的清理工作。这个方法有垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object 类中定义的,因此,所有的类都继承类它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。 finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。