当前位置: 首页 > news >正文

Java 面试题:谈谈 final、finally、 finalize 有什么不同?

在 Java 编程中,finalfinallyfinalize 是三个看似相似但用途截然不同的关键字和方法。理解它们的区别对于编写高质量和健壮的代码至关重要。

final 关键字可用于声明常量、方法和类。用在变量上表示变量不可变,用在方法上表示方法不能被重写,用在类上表示类不能被继承。它在确保程序稳定性和安全性方面起着重要作用。

finally 是异常处理机制的一部分,用于定义在 trycatch 块执行后必须执行的代码。无论是否发生异常,finally 块中的代码都会被执行,用于清理资源等操作,确保程序能够正确地释放资源。

finalizeObject 类中的一个方法,用于对象被垃圾回收器回收之前的清理工作。尽管 finalize 方法在理论上可以用于资源回收,但由于其不确定性和性能问题,在实际编程中很少被使用。

通过探讨这些关键字和方法的区别,可以帮助你更深入地理解 Java 的内存管理和异常处理机制,从而编写出更健壮和高效的代码。


文章目录

      • 1、面试问题
      • 2、问题分析
      • 3、典型回答
      • 4、问题深入
        • 4.1、解释final在类、方法和变量中的具体作用和意义
        • 4.2、讨论finally块的执行时机和特例情况
        • 4.3、解释finalize方法的工作原理和为什么不推荐使用
        • 4.4、讨论使用final关键字的最佳实践
        • 4.5、讨论try-with-resources语句及其优势
        • 4.6、讨论Java 9引入的Cleaner机制


1、面试问题

今天的面试问题:谈谈final、finally、finalize有什么不同?


2、问题分析

这个问题主要考察以下几个关键点:

  1. 语法和定义:了解finalfinallyfinalize的基本定义和用法。
  2. 应用场景:掌握它们在实际编程中的应用场景。
  3. 设计目的:理解它们设计的目的和使用中的注意事项。
  4. 性能和最佳实践:了解它们在性能和最佳实践方面的影响和推荐使用方式。

这个问题不仅考察基础知识,还涉及Java编程的语法、内存管理和异常处理机制,是评估Java开发者技能的一个重要方面。


3、典型回答

final:

  • 定义:final关键字可以用来修饰类、方法和变量。

  • 用法:

    • 修饰类:表示该类不能被继承。

      public final class FinalClass {// Class implementation
      }
      
    • 修饰方法:表示该方法不能被重写。

      public class ParentClass {public final void finalMethod() {// Method implementation}
      }
      
    • 修饰变量:表示该变量的值不能被修改。

      public class Example {public static final int CONSTANT = 10;
      }
      
  • 应用场景:用于明确不可修改的类、方法和变量,提供更好的代码安全性和可读性。

finally:

  • 定义:finally块用于保证无论是否抛出异常,都必须执行特定代码。

  • 用法:

    try {// Code that may throw an exception
    } catch (Exception e) {// Exception handling code
    } finally {// Code that will always be executed
    }
    
  • 应用场景:用于资源释放,如关闭文件流、数据库连接等,确保资源不泄露。

finalize:

  • 定义:finalize方法是java.lang.Object类的一个方法,用于在对象被垃圾收集前进行清理操作。

  • 用法:

    @Override
    protected void finalize() throws Throwable {try {// Cleanup code} finally {super.finalize();}
    }
    
  • 应用场景:用于清理资源,但不推荐使用。finalize机制在JDK 9中被标记为deprecated,建议使用其他方式进行资源管理,如try-with-resourcesCleaner机制。


4、问题深入

如果继续深入,面试官可以从各种不同的角度考察,比如可以:

4.1、解释final在类、方法和变量中的具体作用和意义

final 修饰类

  • 作用:表示该类不能被继承,防止类的继承和扩展。
  • 意义:确保类的设计不被改变,特别是对于工具类和不可变类(immutable class)。
  • 示例:
public final class UtilityClass {public static void utilityMethod() {// Utility method implementation}
}
  • 应用场景:用于创建工具类或不可变类,防止类被继承和修改。

final 修饰方法:

  • 作用:表示该方法不能被重写(override)。
  • 意义:确保关键方法的行为不被子类修改,维护方法的逻辑一致性。
  • 示例:
public class ParentClass {public final void criticalMethod() {// Critical method implementation}
}public class ChildClass extends ParentClass {// 不能重写criticalMethod
}
  • 应用场景:用于保护类中的关键方法,防止子类修改其行为。

final 修饰变量:

  • 作用:表示该变量的值一旦初始化后就不能被修改。
  • 意义:确保变量的值不可变,增加代码的安全性和可读性。
  • 示例:
public class Constants {public static final int MAX_SIZE = 100;private final int id;public Constants(int id) {this.id = id;}
}
  • 应用场景:用于定义常量,确保变量在初始化后不被修改。
4.2、讨论finally块的执行时机和特例情况

finally块的执行时机

  • 正常情况下:在try块或catch块执行结束后,finally块中的代码一定会被执行。
  • 异常情况下:即使try块或catch块中抛出了异常,finally块中的代码仍然会被执行。

示例:

try {// Code that may throw an exception
} catch (Exception e) {// Exception handling code
} finally {// Code that will always be executed
}

特例情况

  • System.exit():如果在try块或catch块中调用了System.exit()方法,finally块中的代码不会被执行。
  • 虚拟机崩溃:如果JVM崩溃,finally块中的代码也不会被执行。

示例:

try {System.exit(0); // JVM退出,finally块不会执行
} finally {System.out.println("This will not be printed");
}
4.3、解释finalize方法的工作原理和为什么不推荐使用

finalize方法的工作原理

  • 定义:finalizejava.lang.Object类的一个方法,用于在对象被垃圾收集前进行资源清理。
  • 调用时机:垃圾收集器在回收对象前调用finalize方法,但调用时间不确定。
  • 实现方式:可以在类中覆盖finalize方法来实现自定义的资源清理逻辑。

示例:

public class Resource {@Overrideprotected void finalize() throws Throwable {try {// Cleanup code} finally {super.finalize();}}
}

不推荐使用原因

  • 不确定性:无法保证finalize方法的执行时间,可能导致资源长时间未被释放。
  • 性能问题:增加垃圾收集器的负担,影响性能。
  • 替代方案:建议使用try-with-resourcesCleaner机制进行资源管理。
4.4、讨论使用final关键字的最佳实践

修饰类

  • 最佳实践:用于创建工具类或不可变类,防止类被继承和修改。
  • 示例:
public final class UtilityClass {// Utility methods
}

修饰方法

  • 最佳实践:用于保护类中的关键方法,防止子类修改其行为。
  • 示例:
public class ParentClass {public final void criticalMethod() {// Critical code}
}

修饰变量

  • 最佳实践:用于定义常量,确保变量在初始化后不被修改,增加代码的安全性和可读性。
  • 示例:
public class Constants {public static final int MAX_SIZE = 100;private final int id;public Constants(int id) {this.id = id;}
}
4.5、讨论try-with-resources语句及其优势

定义

  • 定义:try-with-resources是Java 7引入的一种资源管理方式,自动关闭实现AutoCloseable接口的资源。
  • 语法:在try块中声明的资源会在try块结束后自动关闭。

示例:

try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {// Read file
} catch (IOException e) {// Handle exception
}

优势

  • 简化代码:减少显式关闭资源的代码。
  • 自动关闭:自动关闭资源,防止资源泄露。
  • 处理异常:更好地处理异常,简化异常处理逻辑。
4.6、讨论Java 9引入的Cleaner机制

定义

  • 定义:Cleaner是Java 9引入的一种资源清理机制,提供比finalize更安全和高效的资源管理方式。
  • 工作原理:使用Cleaner类来注册对象和清理操作,垃圾收集器在对象被回收时执行清理操作。

示例:

Cleaner cleaner = Cleaner.create();class Resource implements Runnable {@Overridepublic void run() {// Cleanup code}
}Resource resource = new Resource();
cleaner.register(object, resource);

优势

  • 确定性:Cleaner的执行时间更加确定。
  • 性能:减少GC的开销,提高性能。
  • 简单易用:提供更简单的API,方便资源管理。

通过这些详细的解答,面试官可以评估候选人对Java中finalfinallyfinalize的理解深度,以及他们在实际开发中应用这些知识的能力。

相关文章:

  • 【信息学奥赛】CSP-J/S初赛03 计算机网络与编程语言分类
  • idea和maven搭配问题,maven下载失败
  • 面试题 08.14. 布尔运算
  • DOM 加载函数
  • 【C++】平衡二叉树(AVL树)的实现
  • 状态压缩DP——AcWing 291. 蒙德里安的梦想
  • 【国际化I18n使用方法】vue2使用i18简单实现多语种切换,刷新保持,动态数据处理
  • 有哪些重大影响的算法?
  • 如何修复“AI的原罪”
  • 甘肃旅游服务平台的设计
  • 【网络安全学习】漏洞扫描:-04- ZAP漏洞扫描工具
  • Harbor本地仓库搭建003_Harbor常见错误解决_以及各功能使用介绍_镜像推送和拉取---分布式云原生部署架构搭建003
  • 第7章:系统架构设计基础知识-软件架构风格
  • 02 Shell编程之条件语句
  • 【第26章】Vue实战篇之用户信息修改
  • 网络传输文件的问题
  • Akka系列(七):Actor持久化之Akka persistence
  • Android 控件背景颜色处理
  • Cookie 在前端中的实践
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • extjs4学习之配置
  • JavaScript 基本功--面试宝典
  • JavaScript新鲜事·第5期
  • JS专题之继承
  • PAT A1050
  • react-native 安卓真机环境搭建
  • supervisor 永不挂掉的进程 安装以及使用
  • Transformer-XL: Unleashing the Potential of Attention Models
  • ucore操作系统实验笔记 - 重新理解中断
  • vue-loader 源码解析系列之 selector
  • 阿里云应用高可用服务公测发布
  • Spring Batch JSON 支持
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​​​​​​​​​​​​​​Γ函数
  • # dbt source dbt source freshness命令详解
  • $.ajax()参数及用法
  • (el-Date-Picker)操作(不使用 ts):Element-plus 中 DatePicker 组件的使用及输出想要日期格式需求的解决过程
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (推荐)叮当——中文语音对话机器人
  • (一)kafka实战——kafka源码编译启动
  • (转)ObjectiveC 深浅拷贝学习
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • .equals()到底是什么意思?
  • .NET 反射的使用
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .NET/C# 使用反射注册事件
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .Net组件程序设计之线程、并发管理(一)
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...