final 是 Java 中一个关键字,它可以用来修饰类、方法和变量,甚至还可以用来修饰局部变量和参数。
基础使用
- 修饰类
当一个类被声明为final时,它不能被其他类继承。比如StringL类就是是final类型
- 修饰方法
当一个方法被声明为final时,这个方法不能被子类重写。可以用于确保某些关键方法的行为不被改变。虽然不能重写,但是final方法是可以被重载的,这一点需要注意。
class Parent {
final void display() {
System.out.println("This is a final method.");
}
}
class Child extends Parent {
// void display() { // 编译错误,无法重写 final 方法
// System.out.println("Trying to override.");
// }
// 重载
void display(String name) { System.out.println("This is a final method."+name); }
}
当我们用private修饰方法时,都隐式地指定为final的。
- 修饰变量
当一个变量被声明为final时,它的值在初始化后不能再被改变,成为了一个常量。
final int MAX_VALUE = 100;
// MAX_VALUE = 200; // 编译错误,无法修改 final 变量
多线程并发
在并发编程中,多个线程可能会同时访问和修改同一数据。如果数据是可变的,可能会导致数据不一致的情况。
class SharedResource {
private int param;
private final int value;
public SharedResource(int value) {
this.value = value; // 在构造函数中初始化
this.param=10;
}
public int getValue() {
return value;
}
public int getParam() {
return param;
}
}
上述对象在创建的时候,由于指令重排序我们有可能拿到一个未完全初始化的对象,那么该对象里面的普通变量的值可能就是各种数据类型的默认值,而不是实际的值。
而被final修饰的变量,造器结束时,JVM会确保final字段的写操作对所有线程可见,这相当于在构造器结束时插入了一个内存屏障,防止了指令重排序带来的问题。
总结
final关键字,它可以用来修饰类、方法、变量、局部变量和参数,确保了内存可见性、不可变性,防止重排序。