Java 中 final 与 static 的区别
Java 中 final
与 static
的区别
在 Java 中,final
和 static
是两个不同的关键字,它们的核心作用和不可变性特性有本质区别:
一、final
的核心作用
1. 变量(不可变引用)
- 不可重新赋值:
final
修饰的变量一旦初始化后,引用地址不可变(基本类型值不可变,对象类型引用不可变)。 - 对象内容可能可变:若
final
修饰对象引用,对象内部状态可能仍可修改(例如final List
可以add
元素,但不能重新指向新列表)。
final int x = 10;
x = 20; // 编译错误!final List<String> list = new ArrayList<>();
list.add("Hello"); // 允许操作对象内容
list = new ArrayList<>(); // 编译错误!引用不可变
2. 方法(不可重写)
final
方法不能被子类重写,但可以重载。
3. 类(不可继承)
final
类不能被继承(如String
类)。
二、static
的核心作用
1. 类级别成员
static
修饰的变量、方法、代码块属于类,而非实例。- 所有实例共享:修改
static
变量会影响所有实例。
class Counter {static int count = 0; // 所有实例共享Counter() { count++; }
}
2. 无不可变性保证
static
变量默认可变,需配合final
实现常量。
class Config {static int timeout = 100; // 可被修改static final int MAX_SIZE = 1024; // 类常量
}
三、关键区别
特性 | final | static |
---|---|---|
作用目标 | 变量、方法、类 | 变量、方法、代码块、嵌套类 |
不可变性 | 确保引用/值不可变(对象内容可能可变) | 无直接关联,变量默认可变 |
内存归属 | 实例变量或常量 | 类级别变量/方法 |
典型场景 | 常量、不可变逻辑、防止继承/重写 | 共享资源、工具方法 |
四、组合使用:static final
常量
当 static
和 final
结合时,定义类级别的不可变常量:
public class MathUtils {public static final double PI = 3.14159; // 类常量,不可变且全局访问
}
五、总结
final
:确保变量引用/值不可变(对象内容可能可变),或限制方法/类的扩展性。static
:定义类级别成员,与不可变性无关,需结合final
实现常量。- 不可变性 需通过设计实现(如
final
+ 不可变对象),而非单纯依赖关键字。