final修饰类可彻底禁止继承,如string、math类;修饰方法可阻止重写但允许调用,如commit()方法;final类中所有方法自动隐式final,但构造方法除外。

用 final 修饰类或方法,是 Java 中防止继承和重写的最直接、最可靠的手段。
用 final 修饰类:彻底禁止被继承
在 class 关键字前加上 final,该类就无法被任何其他类继承。编译器会在你写 class Sub extends FinalClass 时直接报错。
常见用途:
- 工具类(如
java.lang.Math、java.lang.String)——设计上就不该被扩展 - 安全敏感类(如涉及加密、权限控制的类)——避免子类篡改行为
- 已完全封装、无扩展需求的业务实体(如枚举类本质就是 final 类)
写法示例:
final class ConfigLoader {
public void load() { /* ... */ }
}
此时 class MyLoader extends ConfigLoader 编译不通过。
用 final 修饰方法:阻止子类重写
在返回类型前加 final,该方法就不能在子类中被 @Override。但注意:它仍可被继承、调用,只是不能被修改实现。
适用场景:
- 核心逻辑固定的方法(如模板方法模式中的钩子方法之外的关键步骤)
- 防止子类破坏不可变性(如
String.hashCode()是 final 的) - 性能敏感方法(JVM 可能对 final 方法做内联优化)
写法示例:
class Base {
public final void commit() {
validate();
doPersist();
logSuccess(); // 这些步骤顺序和行为必须严格保证
}
private void validate() { /* ... */ }
private void doPersist() { /* ... */ }
private void logSuccess() { /* ... */ }
}
子类可以调用 base.commit(),但不能重写它。
注意事项与常见误区
- final 类中所有方法自动隐式 final(但构造方法除外,构造方法本来就不能被继承或重写)
- final 不能修饰构造方法、静态代码块、普通代码块——语法错误
- private 方法默认不能被重写,所以加 final 是冗余的(虽合法,但无实际意义)
- final 和 abstract 冲突:类不能既 final 又 abstract;方法也不能既 final 又 abstract 或 synchronized(synchronized 不影响 final,但语义上一般不混用)
替代思路:比 final 更柔性的控制
如果不想一刀切禁用继承,但又想限制扩展方式,可考虑:
- 把类设为 package-private(不写访问修饰符),仅限同包继承
- 使用 sealed 类(Java 17+)明确列出允许继承的子类,比 final 更精细
- 将关键方法设为 private + final,再通过非 final 的 public 模板方法调度(模板方法模式)











