I think the reason why new Test().new C().i works is because class Test is a top-level class and is treated as static. If you were to change your inner class C to be static then new C().i would work.
However, you should NOT access static members in a non-static way.
To access your static field do:
System.out.println(C.i);
Edit:
For those saying that class Test is not static please refer to this stackoverflow answer.
All top-level classes are, by definition, static.
What the static boils down to is that an instance of the class can
stand on its own. Or, the other way around: a non-static inner class
(= instance inner class) cannot exist without an instance of the outer
class. Since a top-level class does not have an outer class, it can't
be anything but static.
Because all top-level classes are static, having the static keyword in
a top-level class definition is pointless.
Just to show you how dumb of an idea it is to access a static field this way I created the following project:
class Test {
class C {
static final int i = 0;
}
public static void main(String[] args) {
// BAD:
System.out.println(new Test().new C().i);
// Correct:
System.out.println(C.i);
}
}
If you compile the class and view it in jd-gui you can see how it was compiled:
class Test {
public static void main(String[] args) {
void tmp13_10 = new Test(); tmp13_10.getClass(); new C(); System.out.println(0);
System.out.println(0);
}
class C {
static final int i = 0;
C() {
}
}
}
Test t = new Test();thent.Cis inappropriate call to typeC. What you can only do is either use outer type likeTest.C.ior usenewto actually create instance ofCwhich will let you accessi(I am sure that there is some Java Language Specification which explains it, hope someone will find it and post it).Test.CTestis not variable, but type. In my exampletis variable.