Вы можете выяснить, что происходит, взглянув на сгенерированный байт-код (вы можете сделать это, перейдя к Tools -> Kotlin -> Show Kotlin Bytecode
и затем выбрав Decompile
в появившейся панели.).Декомпиляция в Java показывает этот код для класса Expr
:
public abstract class Expr {
private Expr() {
}
// $FF: synthetic method
public Expr(DefaultConstructorMarker $constructor_marker) {
this();
}
}
Так что - это не приватный конструктор для сгенерированного класса Expr
со специальным параметром.Затем, как и следовало ожидать, если вы посмотрите, например, на декомпилированный байт-код Const
, вы увидите, что он вызывает этот конструктор:
public final class Const extends Expr {
public Const(double number) {
super((DefaultConstructorMarker)null);
this.number = number;
}
// other fields and methods ...
}
Вы все еще не можете создать подкласс Expr
от Kotlin, потому что компилятор Kotlin знает, что это запечатанный класс из метаданных в файле, и будет учитывать это.
Что касается клиентского кода Java, там вы не можете получить доступ к этому же конструктору самостоятельно, потому чтоDefaultConstructorMarker
является частным пакетом в пакете kotlin.jvm.internal
, в котором он находится, поэтому даже если вы напишите оператор импорта для него вручную, компилятор не допустит его.
Я предполагаю, что пакет-private видимость может быть применена только во время компиляции, и поэтому компилятор Kotlin может выводить байт-код, соответствующий приведенному выше фрагменту (хотя и не совсем уверен).