一句话总结:它就像代码里的「封印」,贴上后某些东西就不能改了。分场景来看:
1. 封印变量:这个值我说了算!
-
基本类型变量(如
int,double):final int age = 18; age = 20; // 报错!封印后不能改值作用:直接锁死数值,禁止修改。
-
引用类型变量(如对象、数组):
final List<String> list = new ArrayList<>(); list.add("Hello"); // ✅ 可以改内容! list = new LinkedList<>(); // ❌ 报错!不能换对象作用:只能固定指向一个对象,但对象内部可以随便改。
2. 封印方法:别动我的实现!
class Parent {
final void doSomething() {
System.out.println("这个方法不能重写!");
}
}
class Child extends Parent {
// ❌ 报错!不能重写 final 方法
void doSomething() { ... }
}
作用:禁止子类覆盖这个方法(比如工具类常用,防止被乱改)。
3. 封印类:禁止继承!
final class StringUtils {
// 工具类的方法
}
// ❌ 报错!final 类不能被继承
class MyStringUtils extends StringUtils { ... }
作用:彻底禁止其他类继承它(比如 String 类就是 final 的,防止被篡改)。
4. 隐藏好处:让代码更安全、更高效
- 安全:避免关键数据被意外修改(比如配置参数)。
- 性能:JVM 可能对
final变量做优化(比如内联)。 - 并发:
final变量多线程下天然安全(初始化后不可变)。
举个实际例子
// 用户信息类,一旦创建不可变
public final class User {
private final String name; // 名字不可改
private final int id; // ID不可改
public User(String name, int id) {
this.name = name;
this.id = id;
}
// 只有 getter,没有 setter
public String getName() { return name; }
public int getId() { return id; }
}
总结口诀
「final 变量不能改,引用只能指一个
方法加上禁重写,类被封印断子嗣
代码安全性能高,多线程里少烦恼!」