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 usar la inheritance simple para la class de datos?
  • Smart-cast y comparación dentro de Expression después de 'is' type-check
  • Error de inyección de Kotlin dagger 2 Android ViewModel
  • Firebase-Firestre no carga la información de 2 documentos simultáneamente
  • ¿El DAO de Kotlin debería ser opcional o nulo?
  • Crear un service independiente en Kotlin
  • Kotlin: los tiros de comparación de maps fallan incluso si los maps son iguales
  • No se puede ejecutar la aplicación hello world como se muestra en O'Reilly - Introducción a la Progtwigción de Kotlin
  • ¿Es posible eliminar el molde sin marcar en Kotlin cuando se usa arrayOfNulls?
  • Kotlin: reference no resuelta: javaClass
  • Encuadernación con vista de Android Kotlin: findViewById vs Butterknife vs Kotlin Android Extension