Java 中的 final关键字详解
在 Java 中,final
是一个非常常用且功能强大的关键字。它可以用于修饰类、方法、变量等,表示“最终的”、“不可改变的”。通过使用 final
,我们可以增强程序的安全性、稳定性和可读性。
1. final 可以修饰的内容
修饰内容 | 是否支持 final |
---|---|
类 | ✅ |
方法 | ✅ |
变量 | ✅ |
局部变量 | ✅ |
参数 | ✅ |
构造器 | ❌ |
2. final 的作用
使用 final
的主要目的是:
- 防止继承或重写:确保类或方法的行为不被修改;
- 保证线程安全:常量一旦初始化就不可变;
- 提高性能:JVM 对
final
成员有优化; - 设计不可变对象(Immutable Object):如
String
、包装类等。
3. 使用示例
3.1 final 修饰类 —— 不可被继承
public final class FinalClass {// ...
}// 编译错误:无法继承 final 类
// public class SubClass extends FinalClass { }
⚠️ 常见例子:
java.lang.String
是final
类,不能被继承。
3.2 final 修饰方法 —— 不可被重写
public class Parent {public final void sayHello() {System.out.println("Hello");}
}public class Child extends Parent {// 编译错误:不能重写 final 方法// public void sayHello() { ... }
}
✅ 用途:
- 防止子类修改父类逻辑;
- 提高安全性与性能(JVM 可以内联调用)。
3.3 final 修饰变量 —— 常量,不可再赋值
① 修饰基本类型变量
public class Example {public static void main(String[] args) {final int MAX = 100;// MAX = 200; // 编译错误:不能再赋值}
}
② 修饰引用类型变量
public class Example {public static void main(String[] args) {final StringBuilder sb = new StringBuilder("Hello");sb.append(" World"); // ✅ 允许修改对象内容// sb = new StringBuilder(); // ❌ 不允许重新赋值}
}
⚠️ 注意:
final
修饰引用类型时,对象本身不可变(即不能再指向新对象),但对象内部状态可以变化。- 若想完全不可变,需结合
Collections.unmodifiableList()
等工具类。
3.4 final 修饰局部变量和参数
public void method(final int value) {// value = 10; // 编译错误:参数是 final 的
}public void anotherMethod() {final String msg;msg = "Final"; // 第一次赋值 OK// msg = "Again"; // 再次赋值会报错
}
✅ 用途:
- 在匿名内部类中访问外部方法的局部变量时,必须是
final
或等效不可变的。
4. final 的注意事项
注意点 | 说明 |
---|---|
必须显式赋值 | final 变量要么在声明时赋值,要么在构造函数中赋值 |
不影响多线程可见性 | final 字段在并发环境下具有“初始化安全性”,但不是线程同步机制 |
不能与 abstract 共存 | final 和 abstract 是对立的概念 |
与 static 搭配使用常见 | 如 public static final int MAX = 100; 表示静态常量 |
5. 常见应用场景
✅ 定义常量
public class Constants {public static final String APP_NAME = "MyApp";public static final int MAX_RETRY = 3;
}
✅ 封装不可变对象
public final class Person {private final String name;private final int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() { return name; }public int getAge() { return age; }
}
✅ 防止子类破坏逻辑
public class Base {public final void init() {// 初始化逻辑,不允许被覆盖}
}
6. 总结对比表
修饰项 | 是否可继承 | 是否可修改 | 是否可重写 |
---|---|---|---|
final class | ❌ | - | - |
final method | ✅ | - | ❌ |
final variable | ✅ | ❌(基本类型) ✅(引用类型内容) | - |
7. 推荐搭配使用
组合 | 说明 |
---|---|
static final | 定义全局常量,如配置信息、固定值 |
final + private | 封装字段,防止外部修改 |
final + immutable objects | 创建真正不可变的对象 |