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() {
    }
  }
}