首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【关于Java的final关键字】

【关于Java的final关键字】

作者头像
艾伦耶格尔
发布2025-08-28 15:35:48
发布2025-08-28 15:35:48
3160
举报
文章被收录于专栏:Java基础Java基础

final 是 Java 中的一个重要关键字,主要用于表示“不可变”或“最终的”,它可以在类、方法和变量三个层面上使用。本文将详细探讨 final 的作用,并补充一些面试中可能会遇到的问题。

一、final 关键字的作用

1. 修饰类:不能被继承

final 修饰一个类时,表示这个类不能被继承,是类继承体系中的最终形态。例如:

代码语言:javascript
复制
final class MyFinalClass { }
// class SubClass extends MyFinalClass { } // 编译错误!
目的:
  • 保证类的封装性和安全性,防止行为被篡改。
  • 典型例子包括 StringInteger 和 LocalDateTime 等不可变类。
追问:为什么 String 要设计成 final 的?

因为 String 是不可变的(immutable),这是其安全性的基石。如果 String 可被继承,就可能被恶意子类修改其行为(比如重写 equals()hashCode()),导致缓存哈希值失效、字符串池混乱及安全漏洞(如 URL、密码被篡改)等。

2. 修饰方法:不能被重写

final 修饰的方法不能在子类中被重写。例如:

代码语言:javascript
复制
class Parent {
    final void doNotOverride() { }
}
class Child extends Parent {
    // void doNotOverride() { } // 编译错误!
}
用途:
  • 保证核心逻辑不被修改(如 Object.getClass()Thread.start())。
  • 提高性能:JVM 可以对 final 方法进行内联优化(inlining),减少虚方法调用开销。
追问:final 方法会影响性能吗?

会!final 方法是编译时绑定(静态绑定),JVM 知道它不会被重写,可以直接内联,提升执行效率。而非 final 的虚方法需要动态绑定,有查虚函数表的开销。

3. 修饰变量:值不可变

分为三种情况:

类型

行为

基本类型

值不能变(常量)

引用类型

引用地址不能变,但对象内容可变

成员变量

必须在构造器或声明时初始化

局部变量

可以延迟赋值,但只能赋一次

例如:

代码语言:javascript
复制
final int x = 10;
// x = 20; // ❌ 编译错误

final StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // ✅ 允许:对象内容可变
// sb = new StringBuilder(); // ❌ 不允许:引用不能变
追问:final 局部变量和普通变量有什么区别?
  • final 局部变量可以在声明时不初始化(称为“blank final”),但必须在使用前赋值,且只能赋一次。
  • 在匿名内部类中,只能访问 final 或 effectively final(实际上不变)的局部变量。这是为了保证内外数据一致性。

二、常见组合与限制

组合

是否允许

原因

final + abstract 类

❌ 不允许

abstract 要求被继承,final 禁止继承,矛盾

final + abstract 方法

❌ 不允许

abstract 要求重写,final 禁止重写,矛盾

final + static

✅ 允许

常用于定义常量:public static final int MAX = 100;

final + private 方法

✅ 允许

但 private 方法本就不能被重写,加 final 意义不大(但合法)

三、final 与线程安全

  • final 变量在多线程环境下具有特殊的语义:
    • final 字段的初始化是线程安全的:JVM 保证一旦对象构造完成,final 字段的值对所有线程可见(无需额外同步)。
    • 这是安全发布(safe publication)的基础,也是不可变对象线程安全的前提。

例如,Stringvalue 数组是 final 的,确保一旦创建,内容不会被修改,多个线程可安全共享。

四、final 的最佳实践

  1. 类如果不希望被继承,应声明为 final(尤其是工具类、不可变类)
  2. 方法如果核心逻辑不能被修改,用 final
  3. 常量使用 public static final
  4. 局部变量如果不会改变,建议声明为 final,提高可读性和安全性(现代 IDE 支持自动提示 effectively final)
  5. 在 Lambda 表达式中,只能引用 final 或 effectively final 的变量

五、总结

final 不只是一个语法关键字,更是一种设计思想——通过限制可变性来提升代码的安全性、可维护性和性能。它是构建不可变对象、线程安全类和高性能系统的重要基石。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、final 关键字的作用
    • 1. 修饰类:不能被继承
      • 目的:
      • 追问:为什么 String 要设计成 final 的?
    • 2. 修饰方法:不能被重写
      • 用途:
      • 追问:final 方法会影响性能吗?
    • 3. 修饰变量:值不可变
      • 追问:final 局部变量和普通变量有什么区别?
  • 二、常见组合与限制
  • 三、final 与线程安全
  • 四、final 的最佳实践
  • 五、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档