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:
- Kotlin lazy var throwing ClassCastException: kotlin.UNINITIALIZED_VALUE
- Android: ¿cómo lograr setOnClickListener en Kotlin?
- Cómo proteger el oyente de desplazamiento sin fin de un reciclador
- Usando RxJava con Handler, restablece Message.what value
- ¿Es posible usar doReturn () y CALLS_REAL_METHODS con mockito-kotlin?
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:
- En lugar de tener un
SneakyType
en mi constructor, guarde toda la información necesaria para build uno y luegoSneakyType
en elExample
. Funciona pero agrega mucha complejidad. - Abandonar que el
Example
sea inmutable y permitir que el constructor llame para configurar unSneaky
- Exponer el
Sneaky
¿No hay forma de imitar la versión de Java?
- Posición de la label `@` en Kotlin cuando se denota el receptor con `this`
- Android Studio falla refactorizando el código generado de kapt "de solo lectura"
- ¿Cómo se comstack el proyecto Java + Kotlin con Maven?
- Kotlin NumberFormatException
- Invocar methods en interfaces con generics
- Resalta múltiples elementos en la vista de list de Android cuando se selecciona
- Kotlin - Nombres de propiedad ofuscados
- Cómo comparar una class <*> contra un tipo primitivo en caja Java sin las advertencias del comstackdor de Kotlin
Veo dos opciones viables:
-
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. -
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) } } }
- Conversión de proyecto de Android con data binding de Java a Kotlin
- Controlador de respuesta de coincidencia con request en VertX