Kotlin 的反射

(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)
            }
        }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容