Clever example! But this is actually a somewhat boring explanation - there is no visibility problem, you just do not have the ability to refer to t1 directly from T3 , because super.super not allowed .
T2 cannot access its own field t1 directly, since it is private (and child classes do not inherit their parent private fields), but super actually an instance of t1 , and since it can refer to private fields super in the same class T2 . There is simply no mechanism for T3 to directly access the private fields of its grandparent t1 class.
Both of these are compiled just thin inside T3 , which demonstrates that T3 can access grandparent private fields:
System.out.println(((T1)this).t1); System.out.println(new T1().t1);
Conversely, this does not compile in either T2 or T3 :
System.out.println(t1);
If super.super was allowed, you can do it from T3 :
System.out.println(super.super.t1);
if I defined 3 classes, A , B , C , A with the protected field t1 and B would inherit from A and C from B , C could refer to A t1 , calling super.t1 , because it is visible here. should not logically coincide with the inheritance of inner classes, even if the field is private, because these private members must be visible due to the fact that they are in the same class?
(I just want to use the OP class names t1 , T2 and T3 )
If t1 were protected , there would be no problem - T3 could refer to the field t1 just like any subclass. The problem arises with private , because the class does not know the fields of the parent classes private and therefore cannot refer to them directly, although in practice they are visible. This is why you should use super.t1 from T2 to even reference the corresponding field.
Despite the fact that with respect to T3 it does not have the t1 field, it has access to the t1 private fields, being in the same external class. Since all you have to do is make this to t1 , and you have a way to access the private field. Calling super.t1 in T2 is (essentially) casting this to t1 , allowing us to reference its fields.