【final、finally和 finalize的区别】

final、finally和 finalize的区别

特性 final​​ (关键字) ​​finally​​ (关键字) finalize()​​ (方法)
实现方式​ 修饰类、方法或变量 ​​与 try-catch块配合使用 在类中重写 Object的 finalize()方法
核心作用​​ 限制继承、重写或修改 ​​确保代码块必然执行(如资源释放 对象被垃圾回收前的清理操作(已废弃)
执行时机​ 编译时检查 运行时在 try-catch后执行 不确定(由GC触发,不保证一定执行)
是否可控制​​ 开发者显式声明 开发者显式编写 由JVM自动调用
现代替代方案​​ 无(仍是重要关键字) 无(仍是异常处理核心) try-with-resources或 AutoCloseable接口
​​线程安全​​ 被 final修饰的变量是线程安全的(不可变) 与线程无关 不保证线程安全(可能被多线程环境下的GC调用)

final关键字在不同场景下的应用

final应用于类

作用​​:禁止其他类继承该类

​​特点​​:

  • 该类不能被任何其他类继承(不能有子类)
  • 类中所有方法隐式为 final(不能被子类重写)
  • 常用于设计不可变类或工具类

典型应用​​:

  • JDK中的String、Integer等包装类都是final类
  • 工具类如Arrays、Collections等

final应用于方法

作用​​:禁止子类重写该方法

​​特点​​:

  • 子类不能重写(override)该方法
  • 但可以被继承和调用
  • 常用于防止核心算法被修改

典型应用​​:

模板方法模式中的固定步骤

安全相关的方法(如加密算法)

final应用于变量

成员变量

​​特点​​:

  • 必须在声明时或构造函数中初始化
  • 初始化后不能被修改
  • 如果是引用类型,引用不可变(对象内容可能可变)
java 复制代码
class Circle {
    private final double radius;  // final成员变量
    
    public Circle(double r) {
        this.radius = r;  // 构造函数中初始化
    }
    
    // 编译错误:不能在普通方法中修改final变量
    // public void setRadius(double r) { this.radius = r; }
}

静态变量(类常量)

规范​​:

  • 命名全大写,单词间用下划线连接
  • 基本类型直接作为常量使用
  • 引用类型应使用不可变对象
java 复制代码
    public static final int MAX_RETRY_COUNT = 3;// 最大重试次数
    public static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(30);// 默认超时时间
    public static final List<String> SUPPORTED_LANGUAGES =
            Collections.unmodifiableList(Arrays.asList("EN", "ZH", "JP"));//  Java 提供了 Collections.unmodifiableList()方法,使集合变成 ​​只读​​

局部变量

​​特点​​:

  • 一旦赋值后不能被修改
  • 可以延迟初始化(不需要声明时立即赋值)
java 复制代码
public class Example {
    // 成员变量(实例变量)
    int num1;       // 默认 0
    static int num2; // 默认 0

    public void method() {
        // 局部变量(必须手动初始化)
        int num3;
        num3 = 10;
        System.out.println(num3);  // 正确
        
        // int num4;
        // System.out.println(num4); // 错误:num4 未初始化
    }
}

final应用于参数

作用​​:

  • 防止参数在方法内被意外修改
  • 明确表达参数不应改变的意图
java 复制代码
public class Main {
    public static void main(String[] args) {
      printName("Bob");  // 输出:Name: Bob
    }

    public static void printName(final String name) {
        // name = "Alice";  // ❌ 编译错误:不能修改 final 参数
        System.out.println("Name: " + name);
    }
}

final应用于对象

  • final只保证引用不变,不保证对象内容不变
java 复制代码
public class FinalObjectDemo {
    public static void main(String[] args) {
        // 创建final对象引用
        final Person person = new Person("Alice", 25);
        
        // 可以修改对象内部状态
        person.setAge(26);  // ✅ 允许
        System.out.println(person);  // 输出: Person[name=Alice, age=26]
        
        // person = new Person("Bob", 30);  // ❌ 编译错误:不能修改final引用
    }
}
相关推荐
CoderYanger17 小时前
动态规划算法-简单多状态dp问题:15.买卖股票的最佳时机含冷冻期
开发语言·算法·leetcode·动态规划·1024程序员节
CoderYanger18 小时前
递归、搜索与回溯-FloodFill:33.太平洋大西洋水流问题
java·算法·leetcode·1024程序员节
CoderYanger21 小时前
动态规划算法-斐波那契数列模型:2.三步问题
开发语言·算法·leetcode·面试·职场和发展·动态规划·1024程序员节
CoderYanger21 小时前
动态规划算法-简单多状态dp问题:16.买卖股票的最佳时机含手续费
开发语言·算法·leetcode·动态规划·1024程序员节
CoderYanger1 天前
C.滑动窗口-求子数组个数-越短越合法——3258. 统计满足 K 约束的子字符串数量 I
java·开发语言·算法·leetcode·1024程序员节
CoderYanger1 天前
动态规划算法-路径问题:9.最小路径和
开发语言·算法·leetcode·动态规划·1024程序员节
CoderYanger1 天前
动态规划算法-路径问题:7.礼物的最大价值
开发语言·算法·leetcode·动态规划·1024程序员节
CoderYanger1 天前
动态规划算法-简单多状态dp问题:12.打家劫舍Ⅱ
开发语言·算法·leetcode·职场和发展·动态规划·1024程序员节
金融小师妹1 天前
机器学习驱动分析:ADP就业数据异常波动,AI模型预测12月降息概率达89%
大数据·人工智能·深度学习·编辑器·1024程序员节
CoderYanger1 天前
动态规划算法-简单多状态dp问题:18.买卖股票的最佳时机Ⅳ
开发语言·算法·leetcode·动态规划·1024程序员节