Visibilidad de Kotlin de los miembros nesteds

Tengo una class con una class anidada y privada. Tengo un patrón Builder , generador de Java estándar, que construye instancias de esta class. No quiero que nadie fuera de mi class pueda ver mi class oculta.

En Java podría hacer esto:

 public class Example { private SneakyType doNotExposeThis; private Example(Builder builder) { // OK 'cause in Java you can access the private // members of a nested class doNotExposeThis = builder.doNotExposeThis; } private static class SneakyType { SneakyType(String x) { // stuff } } public static class Builder { private SneakyType doNotExposeThis; public void addFoo(String something) { doNotExposeThis = new SneakyType(something); } public Example build() { return new Example(this); } } } 

Pero no puedo entender cómo hacer lo mismo en Kotlin:

 class Example(builder: Builder) { private lateinit var doNotExposeThis: SneakyType init { doNotExposeThis = builder.doNotExposeThis } class Builder { // If private or internal I can't access it in Example.init // and if public it gets exposed. val doNotExposeThis: SneakyType fun addFoo(something: String) { // actual construction is quite a bit more complex doNotExposeThis = SneakyType(something) } } } 

Tenga en count que, por el bien de la interoperabilidad de Java, quiero mantener mi creador. También lo quiero porque mi object es complicado de build y quiero que sea inmutable, así que tengo un constructor con muchos setters, sumdores, vals, etc. y luego en init construyo un solo Example inmutable.

Las únicas alternativas que veo son:

  1. En lugar de tener un SneakyType en mi constructor, guarde toda la información necesaria para build uno y luego SneakyType en el Example . Funciona pero agrega mucha complejidad.
  2. Abandonar que el Example sea ​​inmutable y permitir que el constructor llame para configurar un Sneaky
  3. Exponer el Sneaky

¿No hay forma de imitar la versión de Java?

Veo dos opciones viables:

  1. Use el modificador de visibilidad internal :

     class Example private constructor(builder: Builder) { private val doNotExposeThis: SneakyType init { doNotExposeThis = builder.doNotExposeThis } internal class SneakyType(x: String) class Builder { internal lateinit var doNotExposeThis: SneakyType fun addFoo(something: String) { doNotExposeThis = SneakyType(something) } fun build(): Example { return Example(this) } } } 

    Esto hará que SneakyType solo sea visible dentro de su module de compilation de Kotlin.

  2. Haga que el Example independiente de su constructor (esto es lo que recomiendo):

     class Example private constructor(private val doNotExposeThis: SneakyType) { private class SneakyType(x: String) class Builder { private lateinit var doNotExposeThis: SneakyType fun addFoo(something: String) { doNotExposeThis = SneakyType(something) } fun build(): Example { return Example(doNotExposeThis) } } } 
  • Cómo revertir un map en Kotlin?
  • ¿Cómo llamar al súper método de la class externa desde la class interna en Kotlin?
  • Usando la function Kotlin como tipo Java SAM
  • Kotlin - No coincide el tipo: Obligatorio: Cadena, Encontrado: () -> Cadena
  • NullPointerException en android.support.v4.app.NotificationCompatBase $ Action.getIcon ()
  • Delegar propiedad a otra propiedad
  • La extensión de TreeMap en Kotlin falla pelusa
  • ¿Cómo puedo convertir CharArray / Array <Char> en una cadena?
  • Advertencia: la opción '-d' con un destino de directory se ignora porque se especifica '-module'
  • ¿Por qué es posible omitir los valores pnetworkingeterminados en las funciones de miembro reemplazadas de los subtypes?
  • Kotlin Annotation IntDef