我觉得final有两方面内容值得注意。第一个方面是final的修饰效果:
1. final变量只能被赋值一次。static final变量必须在声明的同时初始化,否则就永远不可能再对其赋值,因此不初始化static final变量将引发编译错误。
2. final修饰的实例方法不能被子类重写,final修饰的静态方法不能被子类隐藏
3. final类不能被继承
第二个方面是访问static final成员变量是否会触发类的静态初始化。如果static final成员变量赋的值是编译时就可以确定的常量,则访问这种成员变量不会触发类的静态初始化,否则,类将执行静态初始化。例如:
- public class Tests {
- public static void main(String[] args) {
- String s = Person.name1; // null不是编译时常量,会引发静态初始化
- String s = Person.name2; // 字符串字面值是编译时常量,不会引发静态初始化
- String s = Person.name3; // new对象不是编译时常量,会引发静态初始化
- }
- }
- class Person {
- public static final String name1 = null;
- public static final String name2 = "Jack";
- public static final String name3 = new String("Jack");
- static {
- System.out.println("static initialization");
- }
- }
复制代码 |