问题
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