为什么最终的静态变量不能在实例块中赋值?

时间:2015-03-30 18:27:41

标签: java

class Test {
    static final String name;

    {    
        name = "User"; 
        /* shows error. As i have to assign User as default value */
    }
    final String name1;

    {
       name1 = "User"; // This works but why the above one does not works
    }
}    

我可以使用静态块分配值,但不能通过实例阻止原因吗?

4 个答案:

答案 0 :(得分:5)

因为它是static final,所以它必须在静态上下文中初始化一次 - 当声明变量时或在static initialization block中。

static {    
    name = "User";
}

编辑:静态成员属于该类,非静态成员属于该类的每个实例。如果要在实例块中初始化静态变量,则每次创建该类的新实例时都会初始化它。这意味着它在此之前不会被初始化,并且可以多次初始化。由于它是staticfinal,因此必须初始化一次(对于该类,而不是每个实例一次),因此您的实例块不会执行。

也许您想在Java中更多地研究static vs. non-static variables

EDIT2:以下是可能有助于您理解的示例。

class Test {
    private static final int a;
    private static int b;
    private final int c;
    private int c;

    // runs once the class is loaded
    static {
        a = 0;
        b = 0;
        c = 0;  // error: non-static variables c and d cannot be
        d = 0;  // referenced from a static context
    }

    // instance block, runs every time an instance is created
    {
        a = 0;  // error: static and final cannot be initialized here
        b = 0;
        c = 0;
        d = 0;
    }
}

所有未注释的行都有效。如果我们有

    // instance block
    {
        b++; // increment every time an instance is created
        // ...
    }

然后b将作为创建实例数的计数器,因为它是static并在非静态实例块中递增。

答案 1 :(得分:2)

因为必须在类加载时初始化静态字段。在类加载后调用实例块(在新实例构造时),因此无法更改final static个字段。您可以使用static块来初始化final static fields

答案 2 :(得分:0)

加载类时初始化静态字段。这就是为什么它不会像你试图让它工作的那样工作。

答案 3 :(得分:0)

SIB:它在类加载时执行,并且在整个执行中只执行一次

IIB:它在构造函数被调用但执行构造函数之前执行。因此它执行的次数与构造函数执行次数相同。

让我们看看例子

包com.kb.instanceblock;

公共类SIB1 {

static {
    System.out.println("SIB");
}


{
    System.out.println("IIB");
}

public SIB1() {
    System.out.println("Constructor");
}

public static void main(String[] args) {

SIB1 sib = new SIB1();     }

} 输出

SIB IIB 构造

所以当类加载时,调用SIB并且每当调用构造函数时,IIB执行然后执行构造函数块。

因为我们知道常量变量值应该在它们的声明中定义所以我们不能使用iib来分配静态常量变量