Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

288
Views
¿Por qué se puede llamar al constructor privado de clase sellada en subclase?

La clase sellada en Kotlin solo puede tener un constructor private . Eso significa que podemos llamar al constructor solo en sí mismo:

Las clases selladas no pueden tener constructores no privados (sus constructores son privados por defecto).

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

Pero, cuando utilizamos la clase sellada, una subclase debe heredar la clase sellada:

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

Como puede ver en el código anterior, el constructor private de la clase sellada se llama fuera de la clase sellada. Cuando se crea una instancia de la subclase, se llamará al constructor del padre (clase sellada) antes de llamar al propio constructor de la subclase. ¿Es solo una excepción a los modificadores de visibilidad?

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

Para miembros declarados dentro de una clase: private significa visible solo dentro de esta clase (incluidos todos sus miembros);

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Considere el siguiente código:

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

El código anterior se compila bien, ya que se llama al constructor dentro de la clase A. Si una clase D intenta heredar fuera de A, no se compilará.

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

Como se menciona en la página Clase sellada en Kotlin ,

Una clase sellada puede tener subclases, pero todas ellas deben declararse en el mismo archivo que la propia clase sellada. (Antes de Kotlin 1.1, las reglas eran aún más estrictas: las clases tenían que anidarse dentro de la declaración de la clase sellada).

Parece que Kotlin relajó el requisito de clases anidadas solamente.

Entonces, el siguiente código funciona bien en 1.1+ pero fallaría en versiones anteriores:

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

mientras que el siguiente código habría sido necesario en versiones anteriores a la 1.1, que respeta el constructor privado.

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

Por lo tanto, permitir constructores privados de clases selladas fuera de la clase (pero dentro del mismo archivo) puede considerarse una mejora para hacer que el código sea más limpio.

over 4 years ago · Santiago Trujillo Report

0

Puede averiguar qué está sucediendo al observar el código de bytes generado (puede hacerlo yendo a Tools -> Kotlin -> Show Kotlin Bytecode y luego eligiendo Decompile en el panel que aparece). Descompilarlo a Java muestra este código para la clase Expr :

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

Entonces, hay un constructor no privado para la clase Expr generada, con un parámetro especial. Luego, como era de esperar, si observa el código de bytes descompilado de Const , por ejemplo, verá que llama a este constructor:

 public final class Const extends Expr { public Const(double number) { super((DefaultConstructorMarker)null); this.number = number; } // other fields and methods ... }

Todavía no puede subclasificar Expr de Kotlin, porque el compilador de Kotlin sabe que es una clase sellada de los metadatos en el archivo y lo respetará.

En cuanto al código del cliente Java, no puede acceder a este mismo constructor usted mismo porque DefaultConstructorMarker es un paquete privado en el paquete kotlin.jvm.internal en el que se encuentra, por lo que incluso si escribe la declaración de importación manualmente, el compilador no lo permitirá

Supongo que la visibilidad privada del paquete solo se puede aplicar en el momento de la compilación, y es por eso que el compilador de Kotlin puede generar el código de bytes correspondiente al fragmento anterior (aunque no estoy completamente seguro).

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!