谈一谈你对 final 关键字的理解?什么时候需要用这个关键字来定义呢?
参考回答
final
关键字的作用:
- 修饰变量
- 表示变量的值一旦初始化后,就不能再改变。
- 对于基本数据类型,值不能修改;对于引用类型,引用地址不能改变,但对象的内容可以改变。
- 修饰方法
- 表示方法不能被子类重写。
- 修饰类
- 表示类不能被继承。
使用场景:
- 防止变量值被修改(如常量定义)。
- 防止子类修改父类的重要方法。
- 防止类被继承(如工具类设计)。
详细讲解与拓展
1. final
修饰变量
- 局部变量:
- 必须在声明时或第一次使用前进行初始化,一旦赋值后就不可修改。
- 成员变量:
- 必须在声明时、构造器或代码块中初始化,保证其值在对象生命周期中不变。
- 静态变量:
- 常与
static
一起使用,表示一个全局常量。
- 常与
示例代码:
public class Main {
public static void main(String[] args) {
final int x = 10; // 局部变量
// x = 20; // 编译错误,不能修改 final 变量
final StringBuilder sb = new StringBuilder("hello");
sb.append(" world"); // 可以修改对象内容
// sb = new StringBuilder("new"); // 编译错误,不能修改引用地址
System.out.println(sb);
}
}
总结:
- 基本类型:值不可变。
- 引用类型:引用地址不可变,但内容可变。
2. final
修饰方法
- 子类无法重写被
final
修饰的方法。 - 常用于设计重要或核心方法,防止逻辑被子类改变。
示例代码:
class Parent {
public final void display() {
System.out.println("This is a final method.");
}
}
class Child extends Parent {
// @Override
// public void display() {} // 编译错误,final 方法不能被重写
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.display(); // 调用父类方法
}
}
使用场景:
- 防止关键方法的行为被子类修改。
- 确保设计的一致性,例如模板设计模式中的固定方法。
3. final
修饰类
- 表示该类不能被继承。
- 常用于工具类或不可变类(如
String
),确保其设计不被扩展和破坏。
示例代码:
final class Utility {
public static void printMessage() {
System.out.println("This is a utility class.");
}
}
// class ExtendedUtility extends Utility {} // 编译错误,final 类不能被继承
使用场景:
- 工具类:如
java.lang.Math
。 - 不可变类:如
String
。
4. final
的实际应用场景
- 定义常量
- 常与
static
配合使用,定义全局不可变的值。public class Constants { public static final int MAX_VALUE = 100; }
- 不可变对象
- 类中所有字段均用
final
修饰,确保对象状态不可变。final class ImmutableClass { private final String name; public ImmutableClass(String name) { this.name = name; } public String getName() { return name; } }
- 线程安全
- 使用
final
修饰变量可以避免对象的状态在多线程中被意外修改。public class ThreadSafe { private final int sharedValue = 10; public int getSharedValue() { return sharedValue; } }
- 设计模式中的应用
- 模板设计模式:
final
修饰模板方法,防止子类更改流程逻辑。abstract class Template { public final void process() { // 模板方法 step1(); step2(); } protected abstract void step1(); protected abstract void step2(); }
拓展知识
final
和immutable
的区别final
确保变量、方法或类不能被修改。immutable
通常描述对象的状态不可变,如String
类。
final
的性能优化- 在编译期,
final
变量会被替换为常量,提升性能。 - 编译器和 JVM 可以对
final
方法进行内联优化。
- 在编译期,
final
和finally
、finalize
的区别final
:用于修饰变量、方法、类。finally
:用于保证代码块(如资源释放)一定会执行。finalize
:垃圾回收机制中调用的方法,用于对象回收前的清理操作(不推荐使用)。