当前位置: 首页 > 知识库问答 >
问题:

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

王刚毅
2023-03-14

我遇到了下面的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

下面是IDE :变量USER_ID可能已分配的错误消息。

将值赋值给静态最终变量有问题吗?

共有3个答案

那绪
2023-03-14

因为编译器给了你一个这样的错误,表明这个变量已经在别的地方被创建了(或者被修改了)。只要变量出现在代码中,就改变它的名字是有好处的。

胡彭亮
2023-03-14

事实上,您已经使用赋值操作符在下面的行中抛出了异常:

USER_ID = getUserIdFromEnvironment();

意味着编译器认为存在赋值的可能性,特别是考虑到它被声明为最终状态的事实。

厍彭薄
2023-03-14

最终变量最多允许在构造函数或初始值设定项块中进行一次赋值。这无法编译的原因是 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;
}
 类似资料:
  • 下面的示例类无法编译: 此代码的编译错误消息是: 但是,对于包含以下方法的类,Java不会生成任何错误消息: 关于初始化及其要求,为什么Java对最终实例变量和最终局部变量的处理不同?谢谢

  • 问题内容: 我尝试了解通过引用同一封闭类对象初始化静态字段时初始化顺序的行为。 上面这段代码的输出是: 如果我将变量修改为除plain之外的其他任何内容: 输出为: 为什么会这样呢? 请注意,即使同时声明了两者,输出也是如此,在这种情况下,声明之前 问题答案: 静态最终成员先于其他静态成员初始化。 非最终静态成员按出现顺序初始化 因此,在您的第一种情况下: 构造函数在初始化之前首先被调用,因此被显

  • 问题内容: Java为什么不允许从静态初始化块中引发检查异常?这个设计决定背后的原因是什么? 问题答案: 因为无法在源中处理这些检查的异常。您对初始化过程没有任何控制,并且无法从源代码中调用static {}块,因此可以用try-catch包围它们。 由于您无法处理检查异常指示的任何错误,因此决定禁止抛出检查异常静态块。 静态块不得抛出已检查的异常,但仍允许引发未检查的/运行时异常。但是根据上述原

  • 问题内容: 我想知道为什么默认情况下C,C ++和Java中的确切静态变量初始化为零?为什么对局部变量不是这样? 问题答案: 为什么要对静态变量进行确定性初始化而对局部变量不进行初始化? 了解如何实现静态变量。 它们的内存在链接时分配,并且它们的初始值也在链接时提供。 没有运行时开销。 另一方面,用于局部变量的内存是在运行时分配的。堆栈必须增长。你不知道以前在那里。如果需要,可以清除该内存(将其清

  • 我试图初始化一个静态最终变量。然而,这个变量是在一个可以抛出异常的方法中初始化的,因此,我需要在一个try-catch块中。 即使我知道变量将在try或catch块上初始化,java编译器也会产生错误 最后一个字段a可能已经被赋值 这是我的代码: 我尝试了另一种方法,直接将其声明为null,但它显示了类似的错误(在这种情况下,这对我来说似乎完全是合乎逻辑的) 不能分配最终字段TestClass.a

  • 在信号量(java.util.concurrent.Semaphore)初始化期间,我没有得到负许可背后的基本原理。 我知道调用release()方法最终可能会使信号量的许可证大于等于1( 然而,我没有得到任何实际的用例,在这种情况下,我将使用负许可初始化信号量。 参考样本代码: