【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引用
    }
}
相关推荐
victory04317 小时前
whisper 模型处理音频办法与启示
1024程序员节
Dovis(誓平步青云)7 小时前
《KingbaseES数据库:首个多院区异构多活容灾架构,浙人医创新开新篇》
1024程序员节
Jing_jing_X7 小时前
Spring Boot 启动时,JVM 是如何工作的?
java·后端·spring·1024程序员节
小满、7 小时前
什么是栈?深入理解 JVM 中的栈结构
java·jvm·1024程序员节
方二华8 小时前
5 mysql源码中B+树的构建
数据库·mysql·1024程序员节
侯喵喵8 小时前
Jetson orin agx配置ultralytics 使用docker或conda
yolo·docker·1024程序员节·ultralytics
星火科技探索实验室8 小时前
【实战经验】飞牛云 如何使用 SSD 缓存加速?
1024程序员节
千百元8 小时前
java 程序Apache log4j JDBCAppender SQL注入漏洞(CVE-2022-23305)
1024程序员节
开心-开心急了8 小时前
Kivy 乒乓游戏教程 基于Minconda或Anconda 运行
python·conda·1024程序员节·kivy