面试知识库
基础

final关键字#

一句话答案#

final 修饰类不可继承、方法不可重写、变量不可重新赋值(引用不可变但对象内容可变)。

核心要点

final 可以修饰三种目标,语义各不相同:

1. 修饰变量

  • 基本类型:值不可变(常量)
  • 引用类型:引用地址不可变,但引用指向的对象内容可以改变
final int x = 10;           // x 不能被重新赋值
final List<String> list = new ArrayList<>();
list.add("ok");             // 合法,list 指向的对象内容可变
list = new ArrayList<>();   // 编译报错,引用不可重新指向
java

2. 修饰方法

  • 该方法不能被子类重写(Override)
  • 常用于模板方法中需要固定的步骤

3. 修饰类

  • 该类不能被继承
  • 典型:StringIntegerMath 都是 final
  • 好处:保证安全性(不被恶意子类覆盖),JIT 可做更激进的内联优化

补充:final 与线程安全

  • final 字段在构造函数完成后对其他线程可见(JMM 保证),不需要额外同步
  • 这是 String 不可变且线程安全的基础之一
面试回答(2分钟版)

final关键字可以修饰三种目标,语义各不相同。修饰类表示该类不可被继承,典型的如String、Integer、Math都是final类,目的是保证不可变性和安全性,防止被恶意子类覆盖行为。修饰方法表示不可被子类重写,常用于模板方法模式中需要固定的步骤,但注意final方法可以被重载。修饰变量表示不可被重新赋值,这是面试最容易挖坑的地方:基本类型的final变量值不可变就是常量,但引用类型的final变量只是引用地址不可变,引用指向的对象内容仍然可以修改——比如final List仍然可以add元素,只是不能让引用指向新的List对象。final还有一个和并发相关的重要特性:JMM保证final字段在构造函数完成后对其他线程可见,不需要额外的同步措施,这是String线程安全的基础之一。final方法早期是为了让JVM做方法内联优化性能,但现在JIT编译器已经能自动优化,所以final方法主要是表达设计意图而非性能考量。

追问与易错

追问方向:

  • “final 修饰引用类型意味着什么?”→ 引用地址不可变(不能指向新对象),但引用指向的对象内容仍可修改,如 final List 仍可 add 元素
  • “final 方法能被重载吗?”→ 可以重载(方法签名不同),不能重写(Override);final 限制的是子类覆盖,不影响同类中的方法重载
  • “为什么 String 是 final 类?”→ 保证不可变性:防止子类重写方法破坏不可变契约,确保线程安全、hashCode 缓存、字符串常量池复用和安全性

易错点:

  • ❌ “final 变量就是常量”——引用类型的 final 变量指向的对象内容仍可修改
  • ❌ “final 方法是为了性能”——JDK 早期是为了内联,现在 JIT 自动优化,主要是设计意图