Reputation: 458
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.
Upvotes: 0
Views: 88
Reputation: 181149
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 withfinal
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.
Upvotes: 1
Reputation: 14668
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)
Upvotes: 2
Reputation: 2558
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.
Upvotes: 0