三十四、Java中的final关键字 java中final关键字的用途
Java中的final关键字是一种修饰符,它有着多种用途,主要应用在变量、方法和类上,以指示不可变性或不可覆盖性。
final 关键字修饰不同元素的作用
Java元素 | 作用 |
变量 | 当final修饰基本类型变量时,该变量会变成常量。 |
方法 | final修饰的方法不能被子类重写(override) |
类 | final修饰的类不能被其他类继承。 |
修饰变量(常量)
序号 | 描述 |
1 | 当final修饰一个变量时,这个变量就变成了常量,其值在初始化后就不能被改变。这包括成员变量、局部变量和静态变量。 |
2 | final修饰的成员变量必须在声明时或者在构造器中初始化,否则编译器会报错。 |
3 | final修饰的局部变量可以在声明时初始化,也可以在使用前进行初始化。 |
final int PI = 3.14159; // 一旦赋值,PI的值就无法改变
示例:
public class FinalExample {
final int finalVar = 10; // final成员变量,在声明时初始化
static final int STATIC_FINAL_VAR = 20; // final静态变量
public FinalExample(int value) {
final int localFinalVar = value; // final局部变量,在声明时初始化
}
public void method() {
final int anotherLocalFinalVar; // 可以在声明时不初始化
anotherLocalFinalVar = 42; // 但在使用前必须初始化
}
}
当final修饰引用类型变量时,虽然引用本身不能重新指向其他对象,但是它所指向的对象的内容是可以改变的,也就是说,final引用指向的对象如果是可变的,则其内部状态可以修改。
final List<String> names = new ArrayList<>(); // names不能再指向其他List
names.add("Alice"); // 但是可以修改names所指向的ArrayList的内容
修饰局部变量:
在方法内或代码块中声明的final局部变量,在生命周期内必须一次性赋值,并且之后不能修改其值。
示例:
void someMethod() {
final String name = "John"; // 局部final变量
}
修饰方法
final修饰的方法不能被子类重写(override)。这意味着即使子类继承了含有final方法的父类,也不能提供该方法的新实现。
示例:
class Base {
final void display() {
System.out.println("Base.display()");
}
}
class Derived extends Base {
// 编译错误,不能重写final方法display
// void display() {
// System.out.println("Derived.display()");
// }
}
修饰类
final修饰的类不能被其他类继承。这样的类通常是设计为不可扩展的,以保证类的行为不会被外界改变。
final class ImmutableClass {
// ...
}
// 以下代码会导致编译错误,因为ImmutableClass被声明为final
// class AttemptToExtendImmutableClass extends ImmutableClass {
// // ...
// }
在内部类中的特殊用法:
在内部类中,若要访问外部类的局部变量,该变量必须声明为final,这是因为内部类在创建对象后可能会在外部类方法结束后的某个时刻仍然存活,此时外部类的局部变量可能已经不存在,所以要求这些变量在内部类创建时就是确定不变的。
示例:
public class OuterClass {
public void outerMethod() {
// 局部变量需要声明为final
final int localVar = 100;
// 定义一个匿名内部类,该类访问了外部类的局部变量
class InnerClass {
int innerVar = localVar; // 正确,局部变量localVar被当作final对待
void displayLocalVar() {
System.out.println("局部变量的值:" + localVar); // 可以访问外部方法的final局部变量
}
}
// 创建并使用内部类实例
InnerClass inner = new InnerClass();
inner.displayLocalVar();
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.outerMethod();
}
}
在上述代码中,outerMethod方法内的localVar变量被声明为final,因此在匿名内部类InnerClass中可以直接访问它,并将其值保存到内部类的实例变量innerVar中。即使在outerMethod方法结束后,InnerClass的实例inner仍能继续访问localVar的值,因为它在内部类创建时已经被复制并固定下来。如果不将localVar声明为final,编译器将会报错,因为非final的局部变量在方法执行完毕后不再存在,内部类无法保证对其的持久访问。
总结
通过使用final关键字,可以创建出更安全、更可靠的代码,因为final变量、方法和类都不能被意外地修改或扩展。这有助于减少错误,提高代码的可维护性和可读性。