一.final
可以用来修饰类、方法和变量,表示"不可改变"的含义
1.final修饰类
final类不能被继承
java
// final类 - 不能被任何类继承
final class StringUtils {
// 工具类通常设计为final
public static boolean isEmpty(String str) {
return str == null || str.trim().length() == 0;
}
}
// 编译错误:不能继承final类
// class EnhancedStringUtils extends StringUtils { }
// 正确使用方式:通过组合而不是继承
class MyUtils {
private final StringUtils utils = new StringUtils();
public void myMethod() {
// 使用StringUtils的功能
}
}
2.final类的典型应用
java
// Java标准库中的final类
final class String { } // String类不可变
final class Integer { } // 包装类不可变
final class Math { } // 工具类
final class System { } // 系统类
// 自定义不可变类
final class ImmutablePoint {
private final int x; // final字段
private final int y;
public ImmutablePoint(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
// 没有setter方法,对象一旦创建就不能修改
}
3.final修饰方法
final方法不能被重写
java
class Parent {
// 普通方法可以被重写
public void normalMethod() {
System.out.println("父类普通方法");
}
// final方法不能被重写
public final void finalMethod() {
System.out.println("父类final方法");
}
// private方法隐含是final的
private void privateMethod() {
System.out.println("父类私有方法");
}
}
class Child extends Parent {
@Override
public void normalMethod() {
System.out.println("子类重写普通方法");
}
// 编译错误:不能重写final方法
// @Override
// public void finalMethod() { }
// 这不是重写,而是新方法(因为父类方法是private)
private void privateMethod() {
System.out.println("子类新方法");
}
}
4.final方法的应用
java
class CriticalClass {
// 1. 保护关键方法不被篡改
public final void criticalOperation() {
// 关键业务逻辑,不能被修改
validateInput();
process();
logOperation();
}
// 2. 在构造方法中调用的方法通常声明为final
public CriticalClass() {
initialize();
}
private final void initialize() {
// 初始化逻辑,确保子类不能改变
}
// 3. 模板方法模式中的固定步骤
public final void templateMethod() {
step1(); // 固定步骤
step2(); // 固定步骤
hookMethod(); // 钩子方法,子类可以自定义
step3(); // 固定步骤
}
protected void hookMethod() {
// 默认实现,子类可以重写
}
}
5.final修饰变量
常量,不能修改
常量的命名规范:
- 单个单词:全部大写
- 多个单词:全部大写,单词之间用下划线连接
java
public class FinalLocalVar {
public void example() {
// final局部变量 - 只能赋值一次
final int x;
x = 10; // 第一次赋值
// x = 20; // 编译错误:不能再次赋值
// final在循环中的使用
for (final int i = 0; i < 5; i++) {
// i在每次循环迭代中是final的
System.out.println(i);
}
// 在lambda中使用的变量必须是final或effective final
final String message = "Hello";
Runnable r = () -> System.out.println(message);
// effective final(虽然没有final关键字,但行为像final)
String greeting = "Hi";
// greeting = "Hello"; // 如果取消注释,下面的lambda会编译错误
Runnable r2 = () -> System.out.println(greeting);
}
}