java基础(一)反射注解泛型

  • 反射

public class IocBean {
    private String name;
    public String title = "ioc";
    private static Login login = new Login();
    public IocBean(){

    }

    private IocBean(String name){
        this.name = name;
    }

    private void print(){
        LogUtils.LogE("name = "+this.name);
    }

    private void printName(String name1){
        LogUtils.LogE("name1 = "+name1);
    }

    @Override
    public String toString() {
        return "IocBean{" +
                "name='" + name + '\'' +
                '}';
    }
}
  • 1.反射拿到构造函数
         Class clazz = IocBean.class;
        try {
            //拿到公有的构造
            Constructor constructor1 = clazz.getConstructor();
            //拿到私有的构造
            Constructor constructor = clazz.getDeclaredConstructor(String.class);
        } catch (NoSuchMethodException e) {
            LogUtils.LogE(e.toString());
        }
  • 2.通过构造去创建对象
        //拿到公有的构造
        Constructor constructor1 = clazz.getConstructor();
        //拿到私有的构造
         Constructor constructor = clazz.getDeclaredConstructor(String.class);
        //有参
         IocBean instance = (IocBean) constructor.newInstance("digta");
         //无参
         IocBean instance1 = (IocBean) constructor1.newInstance();
  • 3.反射获取属性修改属性
        //拿公有属性
         Field field = clazz.getField("title");
         String title = (String) field.get(instance);
        //修改属性
         field.set(instance,"update title");
         //拿私有属性
         Field field1 = clazz.getDeclaredField("name");
         field1.setAccessible(true);
         String name = (String) field1.get(instance); 
         field1.set(instance,"update name");
         //获取静态属性
         Field field2 = clazz.getDeclaredField("login");
         field2.setAccessible(true);
         Login login = (Login) field2.get(null);     
  • 4.反射执行私有方法
  //反射执行方法
            Method method = clazz.getDeclaredMethod("print");
            method.setAccessible(true);
            method.invoke(instance);
            
            Method method1 = clazz.getDeclaredMethod("printName",String.class);
            method1.setAccessible(true);
            method1.invoke(instance,"methodName");
  • 注解

  • 1.RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
  • 2.RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
  • 3.RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;

这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码。
一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解.

  • 1.@Target(ElementType.TYPE) //接口、类、枚举
  • 2.@Target(ElementType.FIELD) //字段、枚举的常量
  • 3.@Target(ElementType.METHOD) //方法
  • 4.@Target(ElementType.PARAMETER) //方法参数
  • 5.@Target(ElementType.CONSTRUCTOR) //构造函数
  • 6.@Target(ElementType.LOCAL_VARIABLE)//局部变量
  • 7.@Target(ElementType.ANNOTATION_TYPE)//注解
  • 8.@Target(ElementType.PACKAGE) ///包
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ViewId {
    int value();
}
    @ViewId(R.id.tv_ioc)
    private TextView mTextView;
    @ViewId(R.id.tv_ioc1)
    private TextView mTextView1;
    @Override
    protected void initView(View rootView) {
        //test1();
        InjectUtils.inject(this,rootView);
        mTextView.setText("ioc set hello");
        mTextView1.setText("ioc set1 hello1");
    }

    public static void inject(IocFragment iocFragment, View rootView) {
        Class aClass = iocFragment.getClass();
        Field[] fields = aClass.getDeclaredFields();

        LogUtils.LogE(fields.length);
        for (Field field : fields) {
            ViewId annotation = field.getAnnotation(ViewId.class);
            if (annotation != null) {
                int value = annotation.value();
                View view = rootView.findViewById(value);
                field.setAccessible(true);
                try {
                    field.set(iocFragment,view);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  • 泛型

    1. ? extends E 规定上边界
//必须是Activity或它的子类
 public static void startActivity(Context context, Class clazz){
        context.startActivity(new Intent(context,clazz));
    }
    1. ? super E 规定下边界
//必须是BaseActivity或者它的父类
  public static void startActivity(Context context, Class clazz){
        context.startActivity(new Intent(context,clazz));
    }
    List list = new ArrayList<>();
    //这里会报错,因为Person的子类有很多种,list无法确定是哪一种,这里只能用get方法取值,得到的都是Person
    list.add(new Person());
    Person person = list.get(0);

    List list = new ArrayList<>();
   //这样写不会报错,list将所有元素都当做是Person加入
    list.add(new Person());
  • 3.方法泛型
//作用于方法上, 省去强转的麻烦
  public  T getView(View view,int id){
        return (T)view.findViewById(id);
    }

你可能感兴趣的:(java基础(一)反射注解泛型)