kotlin reflection get list of fields

27,845

Solution 1

Did you want fields as-in "backing field" or fields as in "properties" ... Kotlin really only has properties. You can get these for some class using:

MyTest::class.memberProperties

// or 

MyTest::class.declaredMemberProperties

And from a Java Class<T>, use the kotlin extension property to get the Kotlin KClass<T> from which you can proceed:

someClassOfMine.javaClass.kotlin.memberProperties

This requires the kotlin-reflect dependency as well to be added to your build and classpath. You'll find many other useful things on KClass

For the secret backing fields behind a property, use Java reflection at your own risk.

Solution 2

Very easy now with Kotlin v1.1, You can use the following method to get the fields in kotlin

val fields = MyClass.javaClass.kotlin.members

Where MyClass is the class of your choice.

In order to use this you need to have kotlin-reflect included in your gradle build file as below

compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

Additionally, it is also possible to get the fields from the javaClass directly if you need java fields (useful in some cases as these cover a slightly different scope)

val fields = MyClass.javaClass.declaredFields

Solution 3

Simple answer

In you build.gradle (app) file

implementation("org.jetbrains.kotlin:kotlin-reflect:$kotlin_version")

And then

val fields = YourClass::class.declaredMemberProperties
for (i in fields){
    Log.e("Fields ===", i.name)
}

Cheers!!!

Solution 4

You can't do this in Kotlin, but there is a dirty unreliable way to do this in java. You can use java reflection. Like this:

public class TestClass {

    trait EmptyTrait
    class EmptyClass

    public var anotherVar:Int? = null
    public val contant:Float = 10f
    private var emptyTrait:EmptyTrait? = null
    val emptyClass:EmptyClass = EmptyClass()

    public fun setVal(fieldName: String, value: Int) {
        javaClass.getDeclaredField(fieldName).set(this, value);
    }

    public fun getFieldNames(): String {
        return javaClass.getDeclaredFields().map{it.getName()}.join(", ")
    }    
}

Let's test it:

val t = TestClass()
Log.v("MainActivity", "Fields: " + t.getFieldNames())
Log.v("MainActivity", "anotherVar: " + t.anotherVar)
t.setVal("anotherVar", 10)
Log.v("MainActivity", "anotherVar: " + t.anotherVar)

Results:

Fields: anotherVar, emptyClass, emptyTrait, contant, $kotlinClass
anotherVar: null
anotherVar: 10

it works )

Solution 5

There is a method in Kotlin that works without having to add a new dependency in a project:

Suppose a custom class called Mine

class Mine(var prop:String) {
    fun myMethod():Boolean {
        return true
    }
}

A new user function called isMethod

fun isMethod(t:Any, s:String):Boolean {
try  {
    t.javaClass.getMethod(s)   // or t::class.java.getMethod(s)
    return true
  } catch(e:Exception)  {
    return false
  }    
}

After one declares an Mine instance and test it.

fun main() {
  var m = Mine("Paulo")  
  println(isMethod(m, "myMethod"))  // it prints true
  println(isMethod(m, "otherMethod"))  // it prints false
}
Share:
27,845
Admin
Author by

Admin

Updated on July 21, 2022

Comments

  • Admin
    Admin almost 2 years

    is there an equivalent for the java reflection foo.getClass().getFields() in Kotlin? I could only find that I can access a field when I know it's name, but I would like to handle fields in a generic way.