Java基础面试题10:Java finally代码块和finalize()方法有什么区别?

在Java开发中,finalfinallyfinalize()常被提到,但它们的作用完全不同。为了让大家更好地理解它们的区别和用法,我们用简单明了的方式分解讲解。


三者的区别

1. 性质不同

  • final 是一个 关键字
  • finalize()方法
  • finally代码块 的标志,专门用在 try 语句中。

2. 作用不同

  • final:用于修饰类、方法或变量,定义为"不可改变"。
  • finalize() :属于 Object 类的方法,用于对象被垃圾回收前的清理工作。
  • finally :配合 try 使用,不论代码是否有异常,finally 中的代码都会执行。

final 的用法

### 1. final 修饰的特点

  1. 修饰类:类不能被继承。
  2. 修饰方法:方法不能被重写。
  3. 修饰变量:变量值不能修改。如果是引用类型,引用地址不能改变,但引用的内容可以变。
  4. 编译优化final 方法可能被 JVM 优化为内联(更高效)。

### 2. 编译器特殊规则

final 修饰的变量和常量在编译阶段会存入常量池,优化访问速度。此外:

  • 构造函数中final 变量的赋值和对象引用赋值顺序不能乱。
  • 多线程中final 提供了更严格的内存排序规则,提高线程安全性。

finally 的用法

### 1. 基本规则

  1. 不论 try 块是否正常结束,finally 块都会执行。
  2. try 块中如果有 returnfinally 仍然会执行。
  3. 返回值是在 finally 执行前就保存好的,finally 不会影响返回值。

### 2. 注意事项

  • 不要在 finally 中使用 return :这会覆盖掉 trycatch 的返回值,造成意外。

示例代码:

java 复制代码
try {
    return 10;  // 返回值暂时保存为 10
} finally {
    System.out.println("执行 finally 块");
    // 此处返回值依然是 10
}

finalize() 的用法

### 1. finalize() 是什么?

finalize()Object 类的一个方法,垃圾回收器回收对象之前会调用它,用于清理资源。

### 2. 特点和局限

  • 不等价于析构函数:不像 C++ 的析构函数,Java 中的垃圾回收不依赖用户手动触发。
  • 无法保证及时性 :垃圾回收器可能不会马上回收对象,finalize() 调用时机不确定。
  • 不可完全依赖finalize() 和垃圾回收机制都不可靠,应尽量使用显式清理方法(如 close())。

### 3. 示例代码

当一个文件对象被垃圾回收时,finalize() 检查资源是否被正确释放:

java 复制代码
public class FileOperator {

    private boolean closed = false;

    void close() {
        this.closed = true;  // 关闭文件
    }

    @Override
    protected void finalize() {  // 对象被回收前调用
        if (!closed) {
            System.out.println("错误:文件未正确关闭!");
            this.closed = true;
        }
    }

    public static void main(String[] args) {
        FileOperator file1 = new FileOperator(); // 有引用,不会被回收
        new FileOperator(); // 无引用,可能被垃圾回收

        System.gc();  // 提醒 JVM 触发垃圾回收
    }
}

### 4. 实践建议

  • 避免依赖 finalize() 做关键清理工作。
  • 推荐使用 try-with-resources 或显式的 close() 方法来管理资源。

总结

特性 final finally finalize()
性质 关键字 代码块 方法
功能 修饰类、方法、变量 保证执行清理代码,无论异常与否 对象被回收前调用,做资源清理工作
使用场景 保证不变性(不可继承、重写、修改等) 异常处理中的清理操作 检查垃圾回收前的资源状态
局限性 不建议包含 return,否则返回值受干扰 调用不可靠,不可完全依赖

通过上面的讲解,finalfinallyfinalize() 的概念和区别已经很清晰了。希望能助你在面试中脱颖而出!

最后说一句(求关注,求赞,别白嫖我)

最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。 这是大佬写的 7701页的BAT大佬写的刷题笔记,让我offer拿到手软

本文,已收录于,我的技术网站 cxykk.com:程序员编程资料站,有大厂完整面经,工作技术,架构师成长之路,等经验分享

求一键三连:点赞、分享、收藏

点赞对我真的非常重要!在线求赞,加个关注我会非常感激!

相关推荐
LUCIAZZZ1 小时前
简单的SQL语句的快速复习
java·数据库·sql
komo莫莫da1 小时前
寒假刷题Day19
java·开发语言
计算机-秋大田2 小时前
基于微信小程序的电子竞技信息交流平台设计与实现(LW+源码+讲解)
spring boot·后端·微信小程序·小程序·课程设计
S-X-S2 小时前
算法总结-数组/字符串
java·数据结构·算法
linwq82 小时前
设计模式学习(二)
java·学习·设计模式
桦说编程3 小时前
CompletableFuture 超时功能有大坑!使用不当直接生产事故!
java·性能优化·函数式编程·并发编程
@_@哆啦A梦3 小时前
Redis 基础命令
java·数据库·redis
字节全栈_rJF4 小时前
性能测试 —— Tomcat监控与调优:status页监控_tomcat 自带监控
java·tomcat
加油,旭杏4 小时前
【go语言】接口
开发语言·后端·golang
谢大旭4 小时前
ASP.NET Core 中间件
后端·中间件·c#