
Let's see if we can clear it up.Ī constant is a data item whose value cannot change during the program's execution. Added to the complexity are the explanations from various industry professionals will vary greatly. Various textbooks describe constants using different terminology. This inconsistency could be resolved by either tracking constant operations for all methods (which would be a huge change to the language), or by removing non-static inner classes, which IMHO would have been sensible because it is trivial to implement them yourself. So a complex system such as Java has slight inconsistencies, which is annoying but not surprising. However, the JLS requires that anonymous classes are never static ( JLS §15.9.5). It would be reasonably possible for anonymous classes in a static context to be declared static, as static inner classes do not have any of the restrictions of inner classes. Now the really sad thing is that your new Runnable() inner class is created in a static context, so the logically-separate inner class problem does not exist. Likewise, f() is not a constant expression. In practice this should not be a problem because the String class is immutable, but the JLS does not special-case the String class. However, CONSTANT1.length() is not a constant expression because you are invoking a method. So an inner class can contain the constant static final String CONSTANT1 = "foo". All Java has is a concept of constant expressions (JLS §15.28): basically just literals and arithmetic. C++ has such a mechanism and can mark methods as const and even constexpr for compile-time computable operations. Reassignment can be prevented with final, but Java has no mechanism to track mutating and non-mutating operations. I believe this restriction is sensible, given the implementation of inner classes. This breaks the logical separation, unless the static fields are constants (see JLS §8.1.3) and cannot be mutated, that is: they cannot be reassigned, and cannot change their value. This means that static fields are shared amongst all inner classes. While the inner classes are logically distinct, they share the same physical class. Inner classes belong to an instance of the outer class, not to the outer class itself. Usually, static fields can be initialized with arbitrary expressions, as long as they do not reference instance variables. You have found an interesting edge case where a guard against invalid behaviour creates a false negative. Java tries to behave sensibly, but since it is a quite complex language, it does occasionally fail. So, does anyone know the technical reasons behind this limitation imposed by the java compiler? Why is modifier 'static' only allowed in constant variable declarations in anonymous class instances? What is the difficulty with allowing 'static' in these cases? Outside of the editor, the compiler reports the error as follows: java: Illegal static declaration in inner class modifier 'static' is only allowed in constant variable declarations. In the editor of the IDE (IntelliJ IDEA) the error reads "Inner classes cannot have static declarations", which is misleading, because if that was the case, then CONSTANT1 would also have an error, but it does not. Private static final int CONSTANT3 = f() //this is fine! Private static final int CONSTANT2 = CONSTANT1.length() //this is fine! Private static int f() //'static' gives error


Private static final int CONSTANT3 = f() //'static' gives error Private static final int CONSTANT2 = CONSTANT1.length() //'static' gives error Private static final String CONSTANT1 = "foo" Private static final Runnable Inner = new Runnable()

Again and again I find myself in situations where I want to do this: class Outer
