Reputation: 10460
I couldn't find any specific SO post referring to this specific case, so I'd like to ask what I think is a yes/no question.
Here's JLS §12.4.2 (Java SE 8), listing 6-7:
- [...] Then, initialize the static fields of C which are constant variables (§4.12.4, §8.3.2, §9.3.1).
- Next, if C is a class rather than an interface, and its superclass has not yet been initialized, then let SC be its superclass [...] For each S in the list [ SC, SI1, ..., SIn ], recursively perform this entire procedure for S. If necessary, verify and prepare S first. [...]
My question: Does it mean that final static variable of a subclass is initialized before the static initialization of the superclass (assuming the final static is initialized as part of its declaration)?
Upvotes: 3
Views: 128
Reputation: 11250
The answer is it might be so. The key part is a constant word meaning.
Consider this code
class Foo {
public static final int FOO_VALUE = 1000;
static {
System.err.println("FOO Bar.BAR_VALUE=" + Bar.BAR_VALUE);
}
}
class Bar extends Foo {
public static final int BAR_VALUE = 2000;
static {
System.err.println("BAR Foo.FOO_VALUE=" + Foo.FOO_VALUE);
}
}
The output of this program will be
FOO Bar.BAR_VALUE=2000
BAR Foo.FOO_VALUE=1000
In this case Bar
static final variables are initialized before Foo
static initialization. Both FOO_VALUE
and BAR_VALUE
are constants so javac
may inline this fields.
But you can trick compiler by pretending that final variable is not a constant in this way
class Foo {
public static final int FOO_VALUE = Integer.valueOf(1000).intValue();
static {
System.err.println("FOO " + Bar.BAR_VALUE);
}
}
class Bar extends Foo {
public static final int BAR_VALUE = Integer.valueOf(2000).intValue();
static {
System.err.println("BAR " + Foo.FOO_VALUE);
}
}
And output will be
FOO Bar.BAR_VALUE=0
BAR Foo.FOO_VALUE=1000
So Foo
static initializer is finished before static final Bar.BAR_VALUE
was initialized.
Upvotes: 2