kotlin reflection get list of fields

久未见 提交于 2021-02-18 09:00:21

问题


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.


回答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.




回答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



回答3:


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
}



回答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 )



来源:https://stackoverflow.com/questions/28391889/kotlin-reflection-get-list-of-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!