Reputation: 59
Why does this line:
static final Integer intValue = 1;
give a compiler error, while this line declared in the same way:
static final String strValue = "aaa";
does not.
The full code:
public class InnerClass {
class NestedClass {
static final String strValue = "aaa";
static final Integer intValue = 1;
}
}
Compile time error:
The field intValue cannot be declared static in a non-static inner type, unless initialized with a constant expression
Upvotes: 5
Views: 336
Reputation: 5754
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"
Upvotes: 4