在声明基本类型的变量时,我们可以使用final
关键字使其成为常量。一旦赋值,这个值将无法再被修改。
final int MAX_VALUE = 100;
// MAX_VALUE = 200; // 重新给MAX_VALUE赋值时,编译错误,无法修改final变量
对于引用类型的变量,final
关键字确保引用不会再指向其他对象,但并不表示引用指向的对象的内容不可变。
final List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
// names = new ArrayList<>(); // 重新给names赋值,编译错误,无法修改final引用
names.add("Charlie"); // 但可以修改引用指向的对象的内容
方法被final修饰的时候,该方法在子类不能被继承。private
作用域的方法可以理解为隐式的final方法,private
作用域的方法同样无法被子类重写。
final方法能不能被重载???
final方法是可以被重载的!!!
class MyClass{
final void myMethod(){
// 该方法不能被重写
}
// final 是可以重载的
// 当然重载的方法必须被final作用,否则编译错误
final void myMethod(String str){
System.out.println(str);
}
}
使用final
关键字修饰类不能被继承,这种设计在某种情况下是非常有用的,例如:为了防止某个类的子类修改其行为。
final class MyFinalClass{
// 该类无法被继承
}
在多线程环境下,使用final
关键字可以增强线程安全性。当一个对象被声明为final
时,其状态无法被修改,从而避免了在多线程环境下的竞争条件。
// ImmutableObject类的实例是不可变的,因为它的状态(value字段)被声明为final,这使得对象在多线程环境下更加安全。
class ImmutableObject {
private final int value;
public ImmutableObject(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
使用final
关键字还可以提高变量的可见性。当一个线程写入final
变量时,其他线程可以立即看到这个变化,而不需要额外的同步机制。
// sharedValue字段被声明为final,确保了多线程环境下对getSharedValue()方法的调用是安全的,不需要额外的同步措施
class SharedResource {
private final int sharedValue;
public SharedResource(int sharedValue) {
this.sharedValue = sharedValue;
}
public int getSharedValue() {
return sharedValue;
}
}
基本数据类型:
final域写
:禁止final域写与构造方法重排序,即禁止final域写重排序到构造方法之外,从而保证该对象对所有线程可见时,该对象的final域全部已经初始化过。final域读
:禁止初次读对象的引用与读该对象包含的final域的重排序。引用数据类型: