2021-07-21 11:11:38
final关键字在Java中有三种主要用法:修饰变量、修饰方法和修饰类,分别用于实现不可变性、阻止方法重写和禁止继承。
修饰变量final修饰变量时,表示该变量一旦被赋值则不可更改。
final成员变量:必须在声明时或构造器中初始化。若类有多个构造器,每个构造器均需确保所有final成员变量被初始化。例如:public class MyClass { private final int x; // 必须初始化 public MyClass(int x) { this.x = x; // 在构造器中初始化 } public int getX() { return x; }}对于引用类型的final成员变量,final仅保证引用不可变(不能指向其他对象),但对象内部状态可修改。例如:public class MyClass { private final List<String> myList; public MyClass(List<String> list) { this.myList = list; // 初始化为传入的list } public void modifyList() { myList.add("new element"); // 合法:修改list内容 } public List<String> getMyList() { return myList; }}若需完全不可变,需使用不可变集合(如Guava的ImmutableList)或手动深拷贝对象。
final局部变量:可在声明后赋值,但只能赋值一次。在lambda表达式和匿名内部类中,只能访问final或effectively final(初始化后未被修改)的局部变量。例如:public void myMethod() { final int y; y = 10; // 第一次赋值 // y = 20; // 错误:不能再次赋值}
修饰方法final修饰方法时,表示该方法不能被子类重写,通常用于保护关键逻辑或提升性能。例如:
public class Parent { public final void myMethod() { System.out.println("Parent's myMethod"); }}public class Child extends Parent { // @Override // public void myMethod() { // 编译错误:不能重写final方法 // System.out.println("Child's myMethod"); // }}final方法可提高代码安全性,防止子类意外修改父类行为。此外,编译器可能对final方法进行内联优化,提升执行效率。
修饰类final修饰类时,表示该类不能被继承,通常用于创建不可变类或防止设计破坏。例如:
public final class ImmutableClass { private final int x; public ImmutableClass(int x) { this.x = x; } public int getX() { return x; }}// class SubClass extends ImmutableClass { // 编译错误:不能继承final类// }String类是典型的final类,其不可变性使其在多线程环境中安全使用,并可作为HashMap的键。
final关键字的好处
final与immutable的区别final仅保证引用不可变,而immutable要求对象状态在创建后不可修改。一个类要成为immutable,需满足:
实际应用场景
性能影响理论上,final方法允许编译器内联优化,但实际效果因JVM智能优化而可能不明显。过度使用final可能降低代码可维护性,需在性能和可维护性间权衡。通常仅在性能瓶颈代码中考虑使用final优化。
总结理解final关键字的用法及其设计思想,对编写高质量Java代码至关重要。正确使用final可提升代码可靠性、安全性、可维护性和性能。