浅谈Java中的final,finally以及finalize

xiaoxiao2021-02-27  187

浅谈Java中的final,finally以及finalize

本文主要是为那些对Java中final,finally以及finalize不是很熟的学习者一个简单参考,本文章的主要参考书籍《Java编程思想》 final模块finally模块finalize模块

final模块

根据上下文环境,Java的关键字final的含义存在着细微的差别,但它通常指的是“这是无法改变的”,原因无非是两种:设计或者效率。 这里主要谈论三个只用到final的方面:数据、方法以及类

final数据

final数据 主要是想编译器告知其指向的数据是恒定不变的,主要的作用是,比如: 1、一个永久不变的编译时常量; 2、一个在运行时被初始化的值,你不希望它改变。

final修饰静态变量

无论 static 还是 final 字段,都只能存储一个数据,而且不得改变。 若随同对象句柄使用 final,而不是基本数据类型,它的含义就稍微让人有点儿迷糊了。对于基本数据类型, final 会将值变成一个常数; 然而,对象本身是可以修改的(简单点说,就是final修饰的那个变量内存储的对象地址不能修改,但是所指向的对象是可以修改的)。 (注:在Java中,根据惯例,及时static优势final的域江永大写表示,并且使用下划线分割各个单词) /* *代码来自于《Java编程思想》 */ class Value { int i = 1; } public class FinalData { // Can be compile-time constants final int i1 = 9; static final int I2 = 99; // Typical public constant: public static final int I3 = 39; // Cannot be compile-time constants: final int i4 = (int)(Math.random()*20); static final int i5 = (int)(Math.random()*20); Value v1 = new Value(); final Value v2 = new Value(); static final Value v3 = new Value(); //! final Value v4; // Pre-Java 1.1 Error: // no initializer // Arrays: final int[] a = { 1, 2, 3, 4, 5, 6 }; public void print(String id) { System.out.println( id + ": " + "i4 = " + i4 + ", i5 = " + i5); } public static void main(String[] args) { FinalData fd1 = new FinalData(); //! fd1.i1++; // Error: can't change value fd1.v2.i++; // Object isn't constant! fd1.v1 = new Value(); // OK -- not final for(int i = 0; i < fd1.a.length; i++) fd1.a[i]++; // Object isn't constant! //! fd1.v2 = new Value(); // Error: Can't //! fd1.v3 = new Value(); // change handle //! fd1.a = new int[3]; fd1.print("fd1"); System.out.println("Creating new FinalData");154 FinalData fd2 = new FinalData(); fd1.print("fd1"); fd2.print("fd2"); } } ///:~

空白final

允许我们创建“空白 final”,它们属于一些特殊的字段。尽管被声明成 final,但却未得到一个初始值。 然而,对于 final 关键字的各种应用,空白 final 具有最大的灵活性。 举个例子来说,位于类内部的一个 final 字段现在对每个对象都可以有所不同,同时依然保持其“不变”的本质。下面列出一个例子 //: BlankFinal.java(代码来自《Java编程思想》) // "Blank" final data members class Poppet { } class BlankFinal { final int i = 0; // Initialized final final int j; // Blank final final Poppet p; // Blank final handle // Blank finals MUST be initialized // in the constructor: BlankFinal() { j = 1; // Initialize blank final p = new Poppet(); } BlankFinal(int x) { j = x; // Initialize blank final155 p = new Poppet(); } public static void main(String[] args) { BlankFinal bf = new BlankFinal(); } } ///:~

final参数

Java允许在参数列表中一声明的方式将参数指明为final。这以为这你无法再发放中更改参数引用所指向的对象。 声明举例:int test(final int i)...

final方法

使用final方法的原因有两个: 1、把方法锁定,以防止任何的继承类修改它,也即不允许覆盖。 2、程序执行的效率。将一个方法设成 final 后,编译器就可以把对那个方法的所有调用都置入“嵌入”调用里。(而不是跳转) class PersonalLoan{ public final String getName(){ return "personal loan"; } } class CheapPersonalLoan extends PersonalLoan{ @Override public final String getName(){ return "cheap personal loan"; //compilation error: overridden method is final } }

final类

如果说整个类都是 final,就表明自己不希望从这个类继承,或者不允许其他任何人采取这种操作。 换言之,出于这样或那样的原因,我们的类肯定不需要进行任何改变;或者出于安全方面的理由,我们不希望进行子类化(子类处理)。 除此以外,我们或许还考虑到执行效率的问题,并想确保涉及这个类各对象的所有行动都要尽可能地有效。 final class FinalClass{...} public class FinalClassTest extends FinalClass{...} //error:Cannot extend final class 'FinalClass'

finally模块

与其他语言的模型相比,finally 关键字是对 Java 异常处理模型的最佳补充。finally 结构使代码总会执行,而不管有无异常发生。 (无论一个违例是否在 try 块中发生,我们经常都想执行一些特定的代码,该部分代码可放于finally中。) 使用 finally 可以维护对象的内部状态,并可以清理非内存资源。 如果没有 finally,您的代码就会很费解。 public class HelloFinally { public static void main(String[] args) { int count = 0; while(true) { try { // post-increment is zero first time: if(count++ == 0) throw new Exception(); System.out.println("No exception"); } catch(Exception e) { System.out.println("Exception thrown"); } finally { System.out.println("in finally clause"); if(count == 2) break; // out of "while" } } } } ///:~

finally用来做什么

在没有“垃圾收集”以及“自动调用破坏器”机制的一种语言中, finally 显得特别重要。 因为程序员可用它担保内存的正确释放—— 无论在 try 块内部发生了什么状况,内存总是会得到释放。 当要把除内存之外的资源恢复到他们的厨师状态是,就要用到finally子句:已经代开的文件或者网络连接。

在return中使用finally

因为finally子句总会被执行,所以在一个方法中,可以从多个点返回,并且可以保证重要的清理工作仍旧要进行。 public class MultipleReturns{ pulic static void test(int i) { try{ System.out.println("Point 1"); if(i == 1) return; System.out.println("Point 2"); if(i == 2) return; System.out.println("Point 3"); if(i == 3) return; System.out.println("END"); }finally{ System.out.println("Performing cleanup"); } } }

finalize模块

Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize()。 (1).对象不一定会被回收。 (2).垃圾回收不是析构函数。 (3).垃圾回收只与内存有关。 (4).垃圾回收和finalize()都是靠不住的,只要JVM还没有快到耗尽内存的地步,它是不会浪费时间进行垃圾回收的。
转载请注明原文地址: https://www.6miu.com/read-12557.html

最新回复(0)