简体   繁体   中英

Why does Java allow static variables which are FINAL in non-static inner classes

We already do understand that non-static inner classes cannot have any member which has a static keyword with it. Yet we see, static member variables with final is being used and encouraged . Can anyone explain why?

Another observation:

final static String abc = "I Love Food"; //works fine

whereas:

final static String abc = null; //is discouraged and gives error.

Read following JLS section (§8.1.3) for rules about usage of static/non-static members in an inner class.

Inner classes may not declare static initializers (§8.7) or member interfaces, or a compile-time error occurs.

Inner classes may not declare static members, unless they are constant variables (§4.12.4), or a compile-time error occurs.

Note this line above - "unless they are constant variables", which answers your question. When you declare a primitive or String as public static final then it becomes a " constant variable " and hence you are able to use it in a non-static inner class because it doesn't break the compilation rules.

Now, why it doesn't break compilation rules because when you declare a constant variable and initialize it then compiler could deterministically say that this would be value of this variable, while if you do not initialize it then compiler cannot deterministically say that this would be value of this variable and wouldn't be sure if it could be modified at runtime, and you cannot change a final value once it is been assigned.

Read rule related to final variable in this JLS section (§4.12.4)

We already do understand that non-static inner classes cannot have any member which has a static keyword with it.

Evidently your understanding is not complete. Section 8.1.3 of version 8 of the JLS specifies, in part,

It is a compile-time error if an inner class declares a member that is explicitly or implicitly static, unless the member is a constant variable (§4.12.4).

(Emphasis added.) Thus an inner class can have static members; there are just fairly strong restrictions on them.

Yet we see, static member variables with final is being used and encouraged . Can anyone explain why?

(Emphasis in the original.) I don't think I often see such usage being encouraged, per se . Nevertheless, it's a sensible way to keep the scope of such constants narrow, which is a good practice.


You furthermore ask about why a static final inner class member cannot be initialized to null . I cannot provide a rationale for that, but the actual rule is spelled out in the JLS, in the definition of a "constant variable" (referenced by the previous excerpt) in section 4.12.4:

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).

Of course, that depends on the definition of a "constant expression" , which is a bit lengthy to present in its entirety. It boils down to an expression of primitive or String type that involve only integer literals, String literals, names designating constant variables, and a fairly large subset of Java's operators. And this brings us to the point: null is neither of primitive type nor of type String , therefore it cannot appear in a constant expression , therefore a variable is not a "constant variable" if it has null or an expression containing null as its initializer. Such a variable, not being a constant variable, cannot appear in an inner class.

If you look at this Accepted Answer Why does Java prohibit static fields in inner classes the referenced section will give you the answer. A final static field is treated as Java's compile time constant.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM