我爱编程

Kotlin 的反射

2018-06-06  本文已影响0人  代瑶

(val obj: Any) 作为参数传过来

val clazz = obj::class
        clazz.declaredMemberProperties.forEach { prop ->
            prop.findAnnotation<Value>() ?: return@forEach
            val mutableProp = try {
                prop as KMutableProperty<*>
            } catch (e: Exception) {
                null
            } ?: return@forEach

            //假如要改变var  并且它是String类型  就这么调用
            //  val javaSetter = mutableProp.javaSetter
            //  javaSetter?.invoke(obj, "反射字段")
         }

据说kotlin 反射很慢,相对java 来说 所以我们可以用java来实现,实现的注解MyValue 一定要是java类
declaredFields 是得到当前类的所有字段 getFields 是得到所有public 字段包括父类

    val clazz = obj::class.java
        for (declaredField in clazz.declaredFields) {
            if (declaredField.isAnnotationPresent(MyValue::class.java)) {
                val forName = Class.forName(declaredField.type.name)
                val newInstance = forName.newInstance()
                declaredField.set(obj, newInstance)
            }
        }
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) //次注解只能作用于方法上
public @interface MyValue {

}

在BaseActivity 中定义一个P 泛型 然后可以这样反射得到类型并赋值

val clazz = obj::class.java
        for (declaredField in clazz.fields) {
            if (declaredField.isAnnotationPresent(MyValue::class.java)) {

                val type = (clazz.genericSuperclass as ParameterizedTypeImpl)
                        .actualTypeArguments[0]
                        as Class<*>
//                val forName = Class.forName(declaredField.type.name)
                val newInstance = type.newInstance()
                declaredField.set(obj, newInstance)
            }
        }

最终实现自动反射得到P和V代码

 val clazz = obj::class.java
        for (declaredField in clazz.fields) {
            if (declaredField.isAnnotationPresent(InjectP::class.java)) {
                val classType = (clazz.genericSuperclass as ParameterizedTypeImpl)
                        .actualTypeArguments[0]
                        as Class<*>
                val presenterInstance = classType.newInstance()
                declaredField.set(obj, presenterInstance)

                //给Presenter
                val presenter = presenterInstance as IBaseContract.Presenter
                val viewField = presenter::class.java.getField("mView")
                viewField.set(presenter, obj)
            }
        }
上一篇 下一篇

猜你喜欢

热点阅读