Search code examples
kotlinencapsulationgetter

Accessing Kotlin field without running it's getter


I have a class that holds a MutableList and the class makes changes to that list. I defined a getter to allow outside modules to get a copy of the list. Problem is whenever i access the field within the class, I end up changing the list copy rather than the actual list. How can I access the list without going through the getter inside the defined class? Is this considered bad practice, if so why?

class Server(private val port: Int): Runnable {

    val clients = mutableListOf<SocketChannel>()
        get() = field.toMutableList()


    private val sel = Selector.open()
    private val serverChannel = NIOServerChannel(port, sel).get()
    private val engine = ServerEngine(sel, clients)

    private val acceptor = ChannelAcceptor(serverChannel, clients)
    private val reader = ChannelReader()
    private val writer = ChannelWriter()
    private val middleware = Middleware()

    override fun run() {
        buildEngine()
        println("Starting server on port: $port")
        engine.run()
    }

    fun use(func: (String, Response) -> Unit) = middleware.add(BiConsumer(func))

    private fun buildEngine() {
        reader.process = middleware.get()

        engine.add(acceptor)
        engine.add(reader)
        engine.add(writer)
    }
}

Solution

  • There doesn't appear to be any convention for accessing an automatically-created backing field. The Kotlin docs on backing fields declare an explicit backing property:

    private val _clients = mutableListOf<SocketChannel>()
    val clients: MutableList<SocketChannel>
            get() = _clients.toMutableList()
    

    Note: I'm not a fan of this syntax since it obliges you to remember which fields you exposed (to access them via _ prefixed names). I would probably use clientsInternal, so my IDE can recommend it and I can select without backtracking to add the _.