Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

290
Vistas
Why private constructor of sealed class can be called in sub class?

Sealed class in Kotlin can have private constructor only. That means we can call the constructor only in itself:

Sealed classes are not allowed to have non-private constructors (their constructors are private by default).

// `private` and `constructor()` are redundant.
sealed class Expr private constructor()

But, when we utilize sealed class, a sub class have to inherit seald class:

// Above Kotlin 1.1
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()

As you can see the code above, sealed class's private constructor is called outside of sealed class itself. When sub class is instantiated, the constructor of parent(sealed class) will be called before sub class's own constructor is called. Is it just exception to visibility modifiers?

https://kotlinlang.org/docs/reference/visibility-modifiers.html#classes-and-interfaces

For members declared inside a class: private means visible inside this class only (including all its members);

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Consider the following code:

open class A private constructor(var name: String){
    class B : A("B")
    class C : A("C")
}

The above code compiles fine, as the constructor is called inside the class A. If a class D tries to inherit outside A, it won't compile.

class D : A("D") // Error: Cannot access '<init>': it is private in 'A'

As mentioned on the page Sealed class in Kotlin,

A sealed class can have subclasses, but all of them must be declared in the same file as the sealed class itself. (Before Kotlin 1.1, the rules were even more strict: classes had to be nested inside the declaration of the sealed class).

It seems that kotlin relaxed the requirement of nested classes only.

So, the following code works fine in 1.1+ but would fail in earlier versions:

sealed class A(var name: String)
class B : A("B")
class C : A("C")

whereas the following code would have been required in versions before 1.1, which respects the private constructor.

sealed class A (var name: String){
    class B : A("B")
    class C : A("C")
}

So, allowing private constructors of sealed classes outside the class (but within the same file) can be considered an enhancement to make the code cleaner.

over 4 years ago · Santiago Trujillo Denunciar

0

You can figure out what's happening by taking a look at the generated bytecode (you can do this by going to Tools -> Kotlin -> Show Kotlin Bytecode and then choosing Decompile in the pane that appears.). Decompiling it to Java shows this code for the Expr class:

public abstract class Expr {
   private Expr() {
   }

   // $FF: synthetic method
   public Expr(DefaultConstructorMarker $constructor_marker) {
      this();
   }
}

So there is a non-private constructor for the Expr class generated, with a special parameter. Then, as you'd expect, if you look at the decompiled bytecode of Const for example, you'll see that it calls into this constructor:

public final class Const extends Expr {
   public Const(double number) {
      super((DefaultConstructorMarker)null);
      this.number = number;
   }

   // other fields and methods ...
}

You still can't subclass Expr from Kotlin, because the Kotlin compiler knows that it's a sealed class from the metadata in the file, and will respect that.

As for Java client code, there you can't access this same constructor yourself because the DefaultConstructorMarker is package-private in the kotlin.jvm.internal package that it's in, so even if you write out the import statement for it manually, the compiler won't allow it.

My guess is that the package-private visibility might only be enforced at compile time, and that's why the Kotlin compiler is able to output the bytecode corresponding to the snippet above (not completely sure though).

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda