JavaSE final 关键字深度解析
面试高频题:「final 含义?可修饰何处?初始化方式有哪些?」本文从语法规则、编译期常量、运行时初始化、面试陷阱四个维度彻底讲透。
核心含义
- final 类:不可被继承(
String、Integer)
- final 方法:不可被重写(锁定实现、提升内联性能)
- final 变量:引用不可变(基本类型值不可变,引用类型地址不可变,但对象内部状态可变)
final 变量两种初始化方式(二选一)
| 方式 | 代码示例 | 适用场景 |
| 声明时显式赋值 | final int MAX = 100; | 编译期常量,编译器内联优化 |
| 构造器/实例初始化块赋值 | final int id; { id = 1; } 或 public Demo(int id){ this.id=id; } | 运行时确定值,每个实例可不同 |
规则:必须在对象构造完成前赋值,且仅赋值一次。静态 final 变量(常量)通常在声明时或静态块初始化。
代码验证
// 1. 直接初始化 + final 类
public final class FinalDemo2 {
final int num = 9;
@Test public void test() { System.out.println(num); } // 9
}
// 2. 构造器初始化
public class FinalDemo {
final int num;
public FinalDemo(int num) { this.num = num; System.out.println(num); }
public static void main(String[] args) { new FinalDemo(8); } // 8
}
面试陷阱集锦
- final 引用指向的对象可变:
final List list = new ArrayList<>();
list.add("a"); // 合法!final 只锁定引用
- 匿名内部类捕获变量必须 final 或 effectively final(JDK 8+ 隐式 final)
- final 方法参数:仅在方法体内禁止重新赋值,不影响调用者
- 编译期常量折叠:
final int A = 10;
final int B = A + 5; // 编译期直接算出 15,字节码无加法指令
- final 与 volatile 的区别:final 保证初始化可见性(JMM 写屏障),volatile 保证读写可见性 + 禁止指令重排
最佳实践
- 默认给不可变字段加
final,利于 JIT 优化、文档自说明、线程安全
- 工具类、DTO、VO、常量类全员
final
- 集合字段
final + Collections.unmodifiableList() 实现真不可变
- 上一篇文章: Spring + Maven + Eclipse 构建 Web 工程:环境准备与项目创建指南
- 下一篇文章: Java NIO 服务端开发实战:Buffer、Channel、Selector 三大核心组件与单线程多路复用模型
Copyright ©
程式碼之家 All Rights Reserved