Это вызвано несоответствием между правилами доступа языка Java и правилами доступа JVM.
JVM не имеет концепции внутренних классов, которая полностью сделана конструкция, изобретенная компилятором Java. Скомпилированный код этого исходного файла состоит из 2 независимых классов.
Когда исходный код:
public class SyntheticConstructor {
private SyntheticConstructor() {}
class Inner {
Inner() { new SyntheticConstructor(); }
}
}
Компилятор генерирует .class
файлов, эквивалентных следующему исходному коду (из javap
дизассемблированный байт-код):
public class SyntheticConstructor extends Object {
private SyntheticConstructor() {
super();
return;
}
}
class SyntheticConstructor$Inner extends Object {
final SyntheticConstructor this$0;
SyntheticConstructor$Inner(SyntheticConstructor outer) {
this.this$0 = outer;
super();
new SyntheticConstructor();
return;
}
}
В этом коде выражение new SyntheticConstructor()
пытается вызвать конструктор private
другого класса. Так как это не разрешено JVM, компилятор должен создать скрытый синтаксический c не приватный конструктор, который он может вызвать вместо этого.
Это верно, когда код во внешнем / внутреннем / вложенном классе обращается к закрытый член другого внешнего / внутреннего / вложенного класса того же класса верхнего уровня.