Why can't we set the value of static final var

2019-03-12 13:11发布

问题:

This question already has an answer here:

  • Why isn't a qualified static final variable allowed in a static initialization block? 2 answers

For example, consider code snap below:

public static final int a;
public static final int b;

static {
    a = 8;       // it's working
    Test.b = 10; // compilation error Test.b cannot be assigned. 
}

Why can't we use Test.b = 10; inside a static block of the Test class itself? Without the class name it's working fine.

Is there any reason behind this?

回答1:

A static final variable must be initialized before use. It may be initialized either directly at declaration time, or in a static block.

But when you use class.var = x it is not seen as an initialization but as an assignation.

With a JDK 7, the error is cannot assign a value to final variable.

That explains why it works if you remove the final keyword

class Test {

    static final int a = 2; // initialization at declaration time
    static final int b;
    static final int c;

    static {
        b = 4;  // initialization in static block
        Test.c = 6; // error : cannot assign a value to final variable c
    }
    ...

}

EDIT

In the JLS the correct word for initialization is definite assignement

Extract from the JLS :

For every access of a local variable or blank final field x, x must be definitely assigned before the access, or a compile-time error occurs.

Similarly, every blank final variable must be assigned at most once; it must be definitely unassigned when an assignment to it occurs.

Such an assignment is defined to occur if and only if either the simple name of the variable (or, for a field, its simple name qualified by this) occurs on the left hand side of an assignment operator.

For every assignment to a blank final variable, the variable must be definitely unassigned before the assignment, or a compile-time error occurs.

emphasize mine, but I think this is the real reason for the error.