Есть тонкость в private
, которую вы, возможно, еще не прогнали. Начиная с JLS 6.6 :
В противном случае член или конструктор объявляется закрытым, и доступ разрешается, если и только если он происходит в теле типа верхнего уровня (§7.6 ), который включает в себя объявление члена или конструктора.
Итак, на данный момент мы забываем о наследовании, что означает, что весь код внутри типа верхнего уровня, включая код внутри вложенных типов, имеет доступ всем закрытым членам, объявленным в одном и том же типе верхнего уровня, включая члены, объявленные во вложенных типах.
Вот пример этого:
public class TopLevel {
private static void foo() {
}
static class Nested1 {
private static void bar() {
}
}
static class Nested2 {
private static void callFooBarFromNested() {
foo();
Nested1.bar();
}
}
private static void callFooBarFromTopLevel() {
foo();
Nested1.bar();
}
}
Оттуда это только маленький шаг чтобы понять, почему ваш первый пример в порядке - конструктор без параметров в C
должен соединиться с конструктором без параметров в B
, что он может делать, когда они оба вложены в один и тот же класс верхнего уровня, но не иначе.