关于 Java 中的 Final、Finally 和 Finalize 你需要知道的一切

如果你之前有过 Java 面试的经验,那么你可能已经注意到面试官往往会问一些棘手的问题,这些问题通常是从基本概念中挑选出来的。 一个最常被问到的问题是在 Java 中区分 finalfinally 和 finalize 。 通过本文的媒介,我将在 Java 中的 finalfinally 和 finalize 之间划清界限,这将帮助大家获得更好的理解。

在本文中,我将介绍以下主题:

  • Final 关键字
  • Finally 块
  • Finalize 方法

那么,让我们从 Java 中的 final、finally 和 finalize 中的第一个关键字开始。

final 关键字

在 Java 中,final 是一个关键字,也可以用作访问修饰符。 换句话说,final关键字用于限制用户的访问。 它可以在各种情况下使用,例如:

  1. final 变量
  2. final 方法
  3. final 类 对于这些中的每一个,最终关键字具有不同的效果。 现在让我们一一看看它如何影响它们中的每一个。

final 变量

每当 Java 中的 final 关键字与变量、字段或参数一起使用时,这意味着一旦传递了引用或完成了实例化,那么它的值就不能在整个程序执行过程中更改。 如果一个没有任何值的变量被声明为 final,那么它被称为空白/未初始化的 final 变量,并且只能通过构造函数进行初始化。

现在让我们看一个例子。

public class A {
    int var1 = 123;
    // 声明 final 变量
    final int var2 = 345;
    final int var3;

    // 试图初始化一个空白的 final 变量
    var =555; // 错误

    A() {
        var1 = 111; //无错误
        var2 = 333; //编译错误

    // 初始化一个空白的 final 变量
        var3 = 444; //无错误
    }

    // 传递 final 参数
    void avg(int param1, final int param2) {
        param1 = 2345; // 无错误
        param2 = 1223; // 编译错误
    }

    // 声明 final 字段
    void show() {
        final int fieldVal = 300000;
        fieldVal = 400000; //错误
    }

}

所以,这都是关于 final 关键字如何影响变量的,现在让我们看看方法是如何受它影响的。

final 方法

在 Java 中,每当一个方法被声明为 final 时,在整个程序执行过程中它都不能被任何子类覆盖。

让我们看一个例子

class A {
    final void method_abc(){
        System.out.println("这是一个 Final 方法,不能被覆盖");
    }

    void method_xyz(){
        System.out.println("这是一个普通的方法,可以被覆盖");
    }
}

class B extends A {
    void method_abc{
        //编译时错误
    }

    void method_xyz(){
        System.out.println("这是 B 类中的重写方法");
    }

}

到目前为止,大家已经看到了声明变量和方法为 final 的结果,现在让我们进一步看看在 Java 中将类声明为 final 时会发生什么。

final 类

在 Java 中,当一个类被声明为 final 时,它不能被任何子类继承。 这是因为,一旦一个类被声明为 final,该类中包含的所有数据成员和方法都将被隐式声明为 final。 此外,一旦一个类被声明为 final,它就不能再被声明为抽象的。 换句话说,一个类可以是两者中的任何一个,final 的或抽象的。

//FINAL CLASS
final class A {
    
}
 
class B extends A{ //编译错误

}

我希望到目前为止,大家已经清楚地了解 final 关键字的工作原理。 那么,现在让我们继续阅读这篇关于 Java 中的 final、finally 和 finalize 的文章,以找出 finally 关键字的作用。


Finally 代码块

在 Java 中,finally 是一个可选块,用于对异常进行处理。 它通常前面有一个 try-catch 块。 finally 块用于执行重要的代码,例如资源清理或释放内存使用等。无论是否处理异常,都会执行 finally 块。 因此,将清理代码封装在 finally 块中被认为是一种很好的做法。 大家也可以将它与 try 块一起使用,而无需任何 catch 块。

package com.zadmei.domain;

class A {
    public static void main(String args[]) {
        try {
            System.out.println("Try Block");
            throw new Exception();
        } catch (Exception e) {
            System.out.println("Catch Block");
        } finally {
            System.out.println("Finally Block");
        }
    }
}

到目前为止,我已经讨论了 Java 中的 final 和 finally 关键字。 现在让我们来看看这三个关键字中的最后一个关键字,即 Java 中的 finalize 关键字。


Finalize 方法

Finalize 是在 Object 类中定义的受保护的非静态方法,因此可用于 Java 中的任何和所有对象。 在对象被完全销毁之前,垃圾收集器会调用此方法。 有时,一个对象可能必须在它被销毁之前完成一些重要的任务,比如关闭一个打开的连接、释放一个资源等。 如果不完成这些任务,可能会降低程序的效率。 因此,垃圾收集器会为不再被引用且已标记为垃圾收集的对象调用它。

此方法被声明为受保护,以限制其在类外部的使用。 但是我们可以在类中覆盖它以在垃圾收集时定义其属性。

让我们看一个相同的例子。

public class A {
    public void finalize() throws Throwable{
        System.out.println("对象被垃圾收集器销毁");
    }
    public static void main(String[] args) {

        Zadmei test = new Zadmei();
        test = null;
        System.gc();
    }
}

至此,我们结束了这篇关于 Java 中的 final、finally 和 finalize 的文章。