当前位置:嗨网首页>书籍在线阅读

05-属性引用

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

10.1.4 属性引用

和函数一样,类的成员属性也可以通过反射来获得。不过Kotlin的编译器在处理类属性时,会将其转换为get和set方法,而不是与属性同名的字段。代码如下。

package com.xzh
class User(){
    var name:String="jack"
        get() = field
        set(v) {
            field=v
        }
}

将上面的User类编译为User.class字节码文件,然后使用javap命令反编译User.class文件后会看到如下代码。

public final class com.xzh.User {
  public final java.lang.String getName();
  public final void setName(java.lang.String);
  public com.xzh.User();
}

可以发现,User类的name属性在编译后生成了getName和setName两个方法,这是Kotlin编译器处理属性特有的功能。如果要使用Java的反射技术来获取属性对象的值,则可以使用getMethod方法,但不能使用getField方法。代码如下。

fun main(args: Array<String>) {
    val user = User()
    var name = User::name
    println(name.get(user))
    name.set(user, "Tom")
    println(name.get(user))
    //编译报错无法通过getField来获取name属性的值
    /*var field=User::class.java.getField("name")
    field.set(user,"Mick")
    println(field.get(user))*/
    //使用getMethod和setMethod来动态设值和取值
    var setName = User::class.java.getMethod("setName", java.lang.String(). 
javaClass)
    setName.invoke(user, "John")
    var getName = User::class.java.getMethod("getName")
    println(getName.invoke(user))}
class User() {
    var name: String = "jack"
        get() = field
        set(v) {
            field = v
        }
}

在上面的实例中,如果在Kotlin文件中使用getField方法来获取属性字段的值,则编译器会报错,因为在编译过程中,根本就没有生成对应字段。