为什么程序不允许初始化静态最终变量?

Ksh*_*ain 9 java static final

我遇到了下面的Java代码,它起初看起来不错但从不编译:

public class UnwelcomeGuest {

    public static final long GUEST_USER_ID = -1;
    private static final long USER_ID;

    static {
        try {
            USER_ID = getUserIdFromEnvironment();
        } catch (IdUnavailableException e) {
            USER_ID = GUEST_USER_ID;
            System.out.println("Logging in as guest");
        }
    }

    private static long getUserIdFromEnvironment()
            throws IdUnavailableException {
        throw new IdUnavailableException(); // Simulate an error
    }

    public static void main(String[] args) {
        System.out.println("User ID: " + USER_ID);
    }
}//Class ends here


//User defined Exception
class IdUnavailableException extends Exception {

     IdUnavailableException() { }

}//Class ends here
Run Code Online (Sandbox Code Playgroud)

以下是IDE中出现的错误消息: 可能已经分配了变量USER_ID.

静态最终变量的赋值是否有问题?

das*_*ght 19

最终变量最多允许构造函数或初始化程序块中的一个赋值.这不编译的原因是Java代码分析器USER_ID在分支中看到两个看起来不相互排斥的赋值.

解决这个问题很简单:

static {
    long theId;
    try {
        theId = getUserIdFromEnvironment();
    } catch (IdUnavailableException e) {
        theId = GUEST_USER_ID;
        System.out.println("Logging in as guest");
    }
    USER_ID = theId;
}
Run Code Online (Sandbox Code Playgroud)

  • 但我希望编译器知道`try`或`catch`块将被执行.所以在运行时应该只有单一的赋值.那么为什么会这样呢? (3认同)
  • @KshitijJain最终变量只允许构造函数或初始化程序块中的一个赋值. (2认同)
  • @RohitJain我怀疑他们采取了更简单的方法:如果分配不是`try`块中的最后一条指令,分析器就是正确的,因为还有另一种可能触发异常. (2认同)
  • @RohitJain我们不希望编译器知道try或catch都会被执行,我们知道有一种情况会执行两者,并且情况是实际上是异常的,因为var被调用了赋值(现在无法再次调用它),异常是catch,然后再次调用var来创建问题.这样做的唯一方法是只在作为dasblinkenglight的任务告诉时调用 (2认同)