Java 中 final、finally 和 finalize 的区别

2025年4月8日 | 阅读 6 分钟

final、finally 和 finalize 是 Java 中用于异常处理的关键字。这些关键字各有不同的功能。final、finally 和 finalize 之间最基本的区别在于:final 是一个访问修饰符,finally 是异常处理中的一个块,而 finalize 是 Object 类的一个方法。

final 关键字

final 是一个用于限制更改的关键字。final 变量不能被重新赋值,final 方法不能被重写,final 类不能被继承。它确保了不变性,通常用于常量。

final 关键字的特点

  • 用于声明常量:一旦赋值,final 变量的值就不能被更改。
  • 防止方法重写:final 方法不能在子类中被重写。
  • 限制继承:final 类不能被任何其他类继承。

final 关键字示例

让我们看下面的例子,其中我们声明了一个 final 变量 age。一旦声明,它就不能被修改。

示例

当我们编译上述程序时,我们会收到以下错误。

Main.java:7: error: cannot assign a value to final variable age
    age = 55;  
    ^
1 error

在上面的例子中,我们声明了一个 final 变量。同样,我们可以使用 final 关键字声明 final 方法和 final 类。

finally 块

finally 是一个与 try-catch 语句一起使用的块,用于执行重要代码,如关闭资源。无论是否发生异常,它都会运行,从而确保执行清理操作。

Java finally 块示例

让我们看下面的例子,其中 Java 代码抛出了一个异常,并且 catch 块处理了该异常。之后,finally 块会在 try-catch 块之后执行。此外,其余代码也会正常执行。

finally 的特点

  • 异常处理的一部分:与 try 和 catch 块一起使用。
  • 始终执行:无论是否抛出或捕获异常,都会运行。
  • 用于资源清理:如关闭文件、数据库连接等。

示例

编译并运行

输出

Inside try block
Exception handled
java.lang.ArithmeticException: / by zero
finally block is always executed
rest of the code...

finalize() 方法

finalize() 是垃圾回收器在销毁对象之前调用的方法。它用于执行清理操作,如释放资源,但它已被弃用,在现代 Java 中不推荐使用。

finalize() 方法的特点

  • 定义在 java.lang.Object 类中:可以被任何类重写。
  • 由垃圾回收器调用:在销毁对象之前。
  • 用于清理:释放文件句柄或网络套接字等资源。
  • 不可靠:不保证它会及时或一定会执行。

finalize() 方法示例

示例

编译并运行

输出

Main method completed.
finalize() method called before object is garbage collected.

Java 中的 final vs finally vs finalize()

下面给出了 final、finally 和 finalize 之间差异的列表

方面finalfinallyfinalize()
定义final 是关键字和访问修饰符,用于对类、方法或变量应用限制。finally 是 Java 异常处理中的块,用于无论是否发生异常,都执行重要代码。finalize 是 Java 中的方法,用于在对象被垃圾回收之前执行清理处理。
适用于final 关键字用于类、方法和变量。Finally 块始终与异常处理中的 try 和 catch 块相关。finalize() 方法与对象一起使用。
功能(1) 一旦声明,final 变量就成为常量,不能修改。
(2) final 方法不能被子类重写。
(3) final 类不能被继承。
(1) finally 块无论是否发生异常,都会运行重要代码。
(2) finally 块会清理 try 块中使用的所有资源。
finalize() 方法在对象销毁前执行清理活动。
执行final 方法仅在我们调用它时执行。finally 块在 try-catch 块执行后立即执行。
它的执行不依赖于异常。
finalize() 方法在对象被销毁前执行。
继承/重写防止方法重写和类继承。与继承或重写无关。可以从 Object 类重写。
用例用于创建常量,防止子类化或方法重写。在异常处理中确保资源清理,如关闭文件、流等。在对象被收集之前执行清理活动,如内存/资源释放。
控制提供编译时控制以避免意外更改。提供运行时控制以在异常后或正常流程中处理清理。由 JVM (Java 虚拟机)调用;程序员不能直接调用它进行清理。
示例final int x=10;Finally{closeResourceprotected void finalize

Final vs Finally vs Finalize 选择题

1. 以下哪个正确描述了 Java 中 final 关键字的用法?

  1. final 用于处理异常。
  2. final 用于将变量、方法或类标记为不可变。
  3. final 用于在对象被垃圾回收之前清理资源。
  4. final 用于声明可以在子类中重写的方法。
 

答案:B

解释:Java 中的 final 关键字可用于标记变量、方法或类。final 变量在初始化后不能被重新赋值,final 方法不能被子类重写,final 类不能被子类化。


2. Java 中 finally 块的目的是什么?

  1. 执行重要代码,例如资源清理,无论是否抛出异常。
  2. 声明一个方法不能被重写。
  3. 将一个变量标记为不可变。
  4. 定义 try-catch 块的可选部分,用于处理特定异常。
 

答案:A

解释:Java 中的 finally 块用于执行必须运行的代码,无论是否抛出异常,例如资源清理。在 try 和 catch 块之后,如果它们存在,finally 块总是会被执行。


3. finalize 方法在 Java 中的正确用例是什么?

  1. 在应用程序退出前执行最终操作。
  2. 在对象被垃圾回收之前处理资源清理。
  3. 声明一个常量值。
  4. 对方法强制执行继承限制。
 

答案:B

解释:Java 中的 finalize 方法在对象从内存中删除之前由垃圾回收器调用。它用于执行清理操作,例如释放系统资源。然而,通常不鼓励使用它,而是倾向于使用其他资源管理技术,如 try-with-resources 和显式资源管理。


4. 关于应用于方法的 final 关键字,以下哪个说法是正确的?

  1. 该方法不能抛出异常。
  2. 该方法不能被子类继承。
  3. 该方法不能被子类重写。
  4. 该方法不能从其他类调用。
 

答案:C

解释:当一个方法被声明为 final 时,意味着它不能被子类重写。这用于防止在子类中更改方法的行为。


5. finally 块如何与 try 或 catch 块中的 return 语句交互?

  1. finally 块中的代码在 return 语句之前执行。
  2. 如果存在 return 语句,finally 块中的代码不会执行。
  3. finally 块中的代码在 return 语句之后执行。
  4. finally 块阻止 return 语句执行。
 

答案:A

解释:finally 块总是在 try 和 catch 块之后执行,但在控制由于 return 语句返回到调用方法之前。这意味着 finally 块中的代码在方法返回一个值之前执行。