[英]kotlin reflection get list of fields
is there an equivalent for the java reflection foo.getClass().getFields()
in Kotlin? Kotlin 中的 java 反射foo.getClass().getFields()
是否有等效项? 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.我只能发现当我知道它的名字时我可以访问一个字段,但我想以通用方式处理字段。
Did you want fields as-in "backing field" or fields as in "properties" ... Kotlin really only has properties.您想要“支持字段”中的字段还是“属性”中的字段...... Kotlin 实际上只有属性。 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:从 Java Class<T>
,使用kotlin
扩展属性获取 Kotlin KClass<T>
,您可以从中继续:
someClassOfMine.javaClass.kotlin.memberProperties
This requires the kotlin-reflect
dependency as well to be added to your build and classpath.这还需要将kotlin-reflect
依赖项添加到您的构建和类路径中。 You'll find many other useful things on KClass
你会在KClass
上找到许多其他有用的东西
For the secret backing fields behind a property, use Java reflection at your own risk.对于属性背后的秘密支持字段,请自担风险使用 Java 反射。
Very easy now with Kotlin v1.1, You can use the following method to get the fields in kotlin现在使用 Kotlin v1.1 非常容易,您可以使用以下方法获取 kotlin 中的字段
val fields = MyClass.javaClass.kotlin.members
Where MyClass is the class of your choice.其中 MyClass 是您选择的类。
In order to use this you need to have kotlin-reflect included in your gradle build file as below为了使用它,您需要将 kotlin-reflect 包含在您的 gradle 构建文件中,如下所示
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)此外,如果您需要 java 字段,也可以直接从 javaClass 获取字段(在某些情况下很有用,因为它们涵盖的范围略有不同)
val fields = MyClass.javaClass.declaredFields
You can't do this in Kotlin, but there is a dirty unreliable way to do this in java.你不能在 Kotlin 中做到这一点,但在 Java 中有一种肮脏不可靠的方法来做到这一点。 You can use java reflection.您可以使用Java反射。 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 )有用 )
There is a method in Kotlin that works without having to add a new dependency in a project: Kotlin中有一种方法无需在项目中添加新的依赖项即可工作:
Suppose a custom class called Mine
假设一个名为Mine
的自定义类
class Mine(var prop:String) {
fun myMethod():Boolean {
return true
}
}
A new user function called isMethod
一个名为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.在声明一个Mine
实例并对其进行测试之后。
fun main() {
var m = Mine("Paulo")
println(isMethod(m, "myMethod")) // it prints true
println(isMethod(m, "otherMethod")) // it prints false
}
Simple answer简单的回答
In you build.gradle (app) file在你的 build.gradle (app) 文件中
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!!!干杯!!!
如果您希望按使用Kotlin-reflect<\/code>声明它们的顺序排列属性:
MyClass::class.primaryConstructor.parameters<\/code>
"
We can use memberProperties
.我们可以使用memberProperties
。
Example:例子:
class Color {
val name: String
val red: Int
val green: Int
val blue: Int
}
// ...
Color::class.memberProperties.size // returns 4
Regarding your example with a foo
variable you may get its backing fields through:关于带有foo
变量的示例,您可以通过以下方式获得其支持字段:
val fields: List<Field?> = foo::class.memberProperties.map { it.javaField }
like this:像这样:
User::class.memberProperties.forEach { member ->
log.i("${member.name} -> ${member.get(this)}")
}
It works very well它运作良好
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.