It is implied that you're using an older version of Java (such as 11), as this is not reproducible with either 17 (openjdk version "17.0.2" 2022-01-18) or 18 (openjdk version "18" 2022-03-22). For this answer, I'm using Java 11 ("11.0.14" 2022-01-18 LTS) as the error you describe is reproducible using that version.
Here's a compilation attempt using Java 11:
% cat Test.java
public class Test {
class NestedClass {
static final Integer intValue = 1;
}
}
% javac -version
javac 11.0.14
% javac Test.java
Test.java:3: error: Illegal static declaration in inner class Test.NestedClass
static final Integer intValue = 1;
^
modifier 'static' is only allowed in constant variable declarations
1 error
Why did that fail? The Java Language Spec (again, for Java 11) states that you cannot define an inner class with a static member, unless that member is a constant:
"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"
Why did it work with a String - static final String strValue = "aaa"? Because a String is a constant:
"A String object has a constant (unchanging) value"
What else besides String is a constant? A final primitive:
"A constant variable is a final variable of primitive type or type String that is initialized with a constant expression"
So what happens if you change the type from Integer to int - does that work? Yes, it works fine:
class InnerClass {
class NestedClass {
static final int intValue = 1; // no problems in Java 11 using primitive
}
}
Or you could try a later Java version, such as 17:
% javac -version
javac 17.0.2
% javac Test.java
%
I did not look further into why later versions allow static final Integer, even though later versions of JLS (such as version 18) still contain the same wording which suggests Integer should not work (even though it clearly does).
"A constant variable is a final variable of primitive type or type String that is initialized with a constant expression"
intIntegeris a class and although you can assign the int literal1to an instance of anIntegerat runtime, it would still result in a wrapper object allocated on the heap, so it's not a constant expression. Changing tointshould make it work. String literals are interned and they get a constant chunk of memory so those are constant expressions.