kotlinreflectionsingletonkotlin-reflect

What's the correct way to iterate through properties of a singleton in Kotlin?


As the title suggests, I wanted to iterate through properties of a singleton object. I tried using the kotlin-reflect as there was no other way I found currently.

object Test {
    const val a = "String"
    const val b = "Another String"
}

Test::class.declaredMemberProperties.forEach {
    println("${it.name}: ${it.get(Test)}")
}

But unfortunately this results in the following exception:

Exception in thread "main" java.lang.IllegalArgumentException: Callable expects 0 arguments, but 1 were provided.
...
at com.example.MainKt.main(main.kt:25)  // same line as println statement
...

It seems like get() function has problem (name property resolves just fine). Is there a better approach (maybe without reflection) or some solution to access those pre-compiled constants in the singleton?


Solution

  • for const val getters, you don't need to pass the receiver object as they are compile-time constants, not runtime constants. that's why the compiler gives you this error: Callable expects 0 arguments. use this code it works fine for both const and non-const:

    object Test {
        const val a = "String"
        val b = "Another String"
    }
    
    fun main() {
        Test::class.memberProperties.forEach {
            if (it.isConst) {
                println("const ${it.name}: ${it.getter.call()}")
            } else {
                println("${it.name}: ${it.getter.call(Test)}")
            }
        }
    }