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:程序员编程资料站,有大厂完整面经,工作技术,架构师成长之路,等经验分享

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

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

相关推荐
捡田螺的小男孩6 分钟前
京东一面:接口性能优化,有哪些经验和手段
java·后端·面试
小白杨树树12 分钟前
【SSM】SpringMVC学习笔记8:拦截器
java·开发语言
艾露z14 分钟前
深度解析Mysql中MVCC的工作机制
java·数据库·后端·mysql
冷心笑看丽美人15 分钟前
Spring MVC 之 异常处理
java·开发语言·java-ee·spring mvc
神仙别闹16 分钟前
基于Java(SpringBoot、Mybatis、SpringMvc)+MySQL实现(Web)小二结账系统
java·spring boot·mybatis
超级小忍16 分钟前
Java集合中Stream流的使用
java·开发语言
前端付豪23 分钟前
揭秘网易统一日志采集与故障定位平台揭秘:如何在亿级请求中1分钟定位线上异常
前端·后端·架构
陈随易40 分钟前
Lodash 杀手来了!es-toolkit v1.39.0 已完全兼容4年未更新的 Lodash
前端·后端·程序员
趁你还年轻_1 小时前
Spring 官方推荐构造函数注入
java·spring·log4j