问题
Quoth JLS #8.1.3:
Inner classes may not declare static initializers (§8.7)......
This is demonstrated as such:
class A {
class B {
static { // Compile-time Error: Cannot define static initializer in inner type A.B
System.out.println("Class is initializing...");
}
}
}
Now since Java's inner (non-static) classes are loaded by class loaders just like every other class, why can't we have static initializers for them?
What's the reason behind this limitation?
回答1:
I think it is because the Inner class is itself non static. From Java point of view it is an instance variable and I suppose that(1) the class loader was not designed to crawl into inner non static classes to find and initialize potentiel static objects.
But it is not in impossibility problem, look at the following example :
public class Outer {
public static class Inner {
Outer owner;
static String constant;
{
constant = "foo";
}
private Inner(Outer owner) {
if (owner == null) {
throw new NullPointerException();
}
this.owner = owner;
}
}
public Inner newInner() {
return new Inner(this);
}
}
Not even a warning because Inner
is declared static.
But at second sight, it has a pointer to an enclosing Outer
instance, can only be created through Outer
because it has only a private constructor, and its owner cannot be null. From a programmer point of view, it has all the constraints for a non static inner class and could be used like one (except for special idioms like Outer.this
), but from a compiler point of view it is static and it static fields will be correctly be initialized at first Outer
class initialization.
(1) : Pacerier explains in below comment why this is incorrect.
回答2:
No Valid Use
just an opinion I came by with, arguments/debates are appreciated
Please read the below thread.
This explains, Why does Java prohibit static fields in inner classes
IMO the same reason also applied to static initializer
. After all, the thing that creating problem is the keyword static
.
Added to the reason explained in above thread, I can give another lame reason.
The name of the block static initializer
give us a hint on when and why to use this block. One does not simply use static initializer block to print hello world [insert the meme here].
The main reason to use this block is clearly to initialize static variable.
Now as inner class/ non-static nested class don't allow static variable, what is the point of allowing static initializer?
回答3:
There's a contradiction by definition:
From JLS §8.1.3:
A statement or expression occurs in a static context if and only if the innermost method, constructor, instance initializer, static initializer, field initializer, or explicit constructor invocation statement enclosing the statement or expression is a static method, a static initializer, the variable initializer of a static variable, or an explicit constructor invocation statement (§8.8.7).
...
When an inner class (whose declaration does not occur in a static context) refers to an instance variable that is a member of a lexically enclosing class, the variable of the corresponding lexically enclosing instance is used.
来源:https://stackoverflow.com/questions/25458617/why-cant-an-inner-class-use-static-initializer