Почему компилятор java создает конструктор syntheti c во внешнем классе? - PullRequest
2 голосов
/ 17 февраля 2020

Я не могу понять oracle java учебник, в котором написано:

public class SyntheticConstructor {
    private SyntheticConstructor() {}
    class Inner {
    // Compiler will generate a synthetic constructor since
    // SyntheticConstructor() is private.
    Inner() { new SyntheticConstructor(); }
    }
}

Поскольку конструктор внутреннего класса ссылается на закрытый конструктор окружающего класса, компилятор должен сгенерировать частный конструктор пакета класса включения (здесь SyntheticConstructor).

Так почему компилятор java должен создать конструктор syntheti c во внешнем классе SyntheticConstructor?

1 Ответ

3 голосов
/ 17 февраля 2020

Это вызвано несоответствием между правилами доступа языка 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 не приватный конструктор, который он может вызвать вместо этого.

Это верно, когда код во внешнем / внутреннем / вложенном классе обращается к закрытый член другого внешнего / внутреннего / вложенного класса того же класса верхнего уровня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...