(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)
}
}