Kotlin, how to retrieve field value via reflection

19,400

Solution 1

Instead of using Java fields and Java reflection code, you can also use Kotlin properties and Kotlin reflection classes:

class Reflector {
    val Foo = 1;

    fun printFields() {
        this::class.memberProperties.forEach {
            if (it.visibility == KVisibility.PUBLIC) {
                println(it.name)
                println(it.getter.call(this))
            }
        }
    }
}

Solution 2

It seems that you are passing the Field variable it as a parameter getInt whereas the parameter should be the object the field belongs to this:

From the Javadoc for Field.getInt(Object obj):

obj - the object to extract the int value from

Perhaps this is what you meant to do:

class Reflector {
    @JvmField val Foo = 1;

    fun printFields() {
        this.javaClass.fields.forEach {
            println(it.isAccessible)
            println(it.getInt(this))
        }
    }
}

fun main(args : Array<String>) {
    Reflector().printFields()
}
Share:
19,400

Related videos on Youtube

elect
Author by

elect

https://github.com/elect86/ https://github.com/kotlin-graphics

Updated on September 14, 2022

Comments

  • elect
    elect over 1 year

    So I have hundreds of fields in a couple of classes and I'd like to write some methods on them where they automatically println each field and its corresponding value

    At the moment I have this:

    inner class Version(val profile: Profile) {
    
        @JvmField val MINOR_VERSION = glGetInteger(GL_MINOR_VERSION)
    
        fun write(file: File? = null) {
            //file.printWriter().use { out -> out.pri }
            this::class.java.fields.forEach {
                println(it.isAccessible)
                println(it.getInt(it)) }
        }
    }
    

    But this is what I get:

    false
    Exception in thread "main" java.lang.IllegalArgumentException: Can not set final int field uno.caps.Caps$Version.MINOR_VERSION to java.lang.reflect.Field
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
        at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
        at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
        at sun.reflect.UnsafeQualifiedIntegerFieldAccessorImpl.getInt(UnsafeQualifiedIntegerFieldAccessorImpl.java:58)
    

    Any idea?

  • elect
    elect almost 7 years
    I guess this is more appropriate
  • quangkid
    quangkid about 6 years
    How about java class?
  • Adam Kis
    Adam Kis almost 5 years
    hey @elect Please check my solution: stackoverflow.com/a/56115232/2939453
  • Damn Vegetables
    Damn Vegetables almost 3 years
    Is this still correct? I don't see memberProperties but only members. Kotlin version 1.5.20.
  • BladeCoder
    BladeCoder almost 3 years
  • DA_123
    DA_123 over 2 years
    @DamnVegetables needs implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"