kotlin reflection get list of fields

后端 未结 4 2286
情书的邮戳
情书的邮戳 2021-02-18 20:51

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

相关标签:
4条回答
  • 2021-02-18 21:19

    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
    
    0 讨论(0)
  • 2021-02-18 21:26

    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 )

    0 讨论(0)
  • 2021-02-18 21:28

    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
    }
    
    0 讨论(0)
  • 2021-02-18 21:30

    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.

    0 讨论(0)
提交回复
热议问题