Java:反射、注解、泛型

一、反射

作用:做一般做不到的事情

使用场景:插件换肤、插件式开发

所有反射功能都是基于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 类> 对象名称  类和其父类

猜你喜欢

转载自blog.csdn.net/weixin_42277946/article/details/131034839