Field:获取自己+父类的成员(不包括private,只能是public)
DecleredField:只能获取自己的成员(不包括父类成员),所有作用域。
注解的应用场景:注解的三个保留级别分别是:源码、字节码、运行时
(1)源码级别:APT技术,在编译器能够获取注解与注解声明的类,包含类中的所有成员信息,一般用于生成额外的辅助类。
(2)字节码:字节码增强,在编译出class后,通过修改class数据以实现修改代码逻辑的目的,对于是否需要修改的区分或者修改为不同逻辑的判断可以使用注解。
(3)反射:在程序运行期间,通过反射动态获取注解及其元素,从而完成不同的逻辑判定。
自己实现类似butterKnife的框架:
(1)自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectView {
@IdRes int value();
}
(2)使用注解加反射
public class InjectUtils {
public static void injectView(Activity activity){
Class cls = activity.getClass();
Field[] declaredFields = cls.getDeclaredFields();
for (Field field:declaredFields){
//判读属性是否被inject注解声明
if (field.isAnnotationPresent(InjectView.class)){
//获取注解
InjectView annotation = field.getAnnotation(InjectView.class);
int id = annotation.value();
View view = activity.findViewById(id);
//反射设置属性的值
field.setAccessible(true);//设置访问权限,允许操作private
try {
//赋值
field.set(activity,view);
}catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
(3)在Activity中使用注解:
public class InjectActivityextends AppCompatActivity {
@InjectView(R.id.tv_content)
TextViewtextView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inject);
InjectUtils.injectView(this);
textView.setText("我是反射后改变的内容");
}
}