本文主要介绍Java中final关键字使用的一些特殊情况,类成员变量和变量默认值。

1、类成员变量和默认值

private static Object x;
public static void main(String[] args) {
System.out.println(x); // Prints 'null'
}

没有明确地指定一个值x,默认值是null。

注意:变量的初始值,每个类变量,实例变量或数组组件在创建时都使用默认值进行初始化。

上面情况不适用于局部变量,例如下面的示例:

public static void main(String[] args) {
    Object x;
    System.out.println(x);
    // 编译时错误:
    // 变量x可能没有初始化
}

2、 final变量

变量可以声明为final。final变量只能赋值一次。如果final变量被赋值,那么它就是编译时错误,除非它在赋值之前确实没有被赋值。

例子,

public static void main(String[] args) {
    System.out.println("After: " + X);
}
private static final long X = assign();
private static long assign() {
    // Access the value before first assignment
    System.out.println("Before: " + X);
    return X + 1;
}

上面代码输出:

Before: 0
After: 1

final变量初始化之后,就不能再赋值,例如,

private static long assign() {
    // final变量X赋值
    X = 1;
    // 方法之后的第二个赋值将崩溃
    return X + 1;
}

final变量自引用初始化

private static final long X = X + 1;
// 编译时错误:
// self-reference in initializer

参考文档

https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.9
https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.10.2
https://docs.oracle.com/javase/specs/jls/se9/html/jls-8.html#jls-8.3.3
https://docs.oracle.com/javase/specs/jls/se9/html/jls-4.html#jls-4.12.4