一、反射
作用:做一般做不到的事情
使用场景:插件换肤、插件式开发
所有反射功能都是基于class字节码,包含三个部分
- Filed:属性
- Constructor:构造函数
- method:方法
public class TestBean { private String name="xiaoming";//属性 public TestBean(String name,int age){// 构造函数 this.name = name; } public void sysName(){//方法 Log.e("TAG",name); } private void say(String desc){ Log.e("TAG",name + " : "+desc); } }
构造方法调用
try { Constructor<TestBean> constructor = TestBean.class.getDeclaredConstructor(String.class, int.class); constructor.setAccessible(true); TestBean testBean = constructor.newInstance("名称", 18); testBean.sysName(); } catch (Exception e) { e.printStackTrace(); }
TestBean testBean = TestBean.class.newInstance(参数类型);
getDeclaredConstructor 从所有的构造方法中找
getConstructor 从公共构造方法中去找constructor.setAccessible(true);//设置权限
方法调用
Method method = TestBean.class.getDeclaredMethod("say",String.class); method.setAccessible(true); method.invoke(constructor,"描述信息");
属性调用
Field field = TestBean.class.getDeclaredField("name"); field.setAccessible(true); String name = (String) field.get(testBean);
二、注解
注解只是一个标识,没有具体的功能
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewById {// @interface 代表注解
int value();
}
@Target:放在哪个位置
- ElementType.METHOD:作用于方法
- ElementType.Type:作用于类
- ElementType.Field:作用于属性
@Retention:
- RetentionPolicy.RUNTIME:运行时,如:xUtils
- RetentionPolicy.CLASS:编译时(打包时),如:ButterKnife
- RetentionPolicy.SOURCE:编程时
注解结合反射解决findViewById注入
public class ViewUtils {
public static void inject(Activity activity) {
// 1.获取所有的属性
Field[] fields = activity.getClass().getDeclaredFields();
// 2.过滤关于 ViewById 属性
for (Field field : fields) {
ViewById viewById = field.getAnnotation(ViewById.class);
if(viewById != null){
// 3.findViewById
View view = activity.findViewById(viewById.value());
// 4.反射注入
field.setAccessible(true);
try {
// activity 属性所在类,view 代表的是属性的值
field.set(activity,view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
三、泛型
类泛型:在任何地方出现的,代表的是同一类型
方法泛型:作用在方法上
上限:类名<? extends 类> 对象名称 类和其子类
下限:类名<? super 类> 对象名称 类和其父类