美文网首页
注解和反射

注解和反射

作者: 安卓_背包客 | 来源:发表于2022-09-03 16:14 被阅读0次

注解

定义数据

companion object {
        const val RESOUCES_ONE = 1;
        const val RESOUCES_TWO = 2;
    }

定义数据

@IntDef({MainActivity.RESOUCES_ONE,MainActivity.RESOUCES_TWO})
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.SOURCE)
public @interface AnnotateValue {
}

输入错误会提示

错误提示

下面解释

@Target:注解的作用目标

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE,

    /**
     * Module declaration.
     *
     * @since 9
     */
    MODULE
}
参数 原文 注解
ElementType.TYPE Class, interface (including annotation type), or enum declaration 类、接口(包括注释类型)或枚举声明
ElementType.FIELD Field declaration (includes enum constants) 字段声明(包括枚举常量)
ElementType.METHOD Method declaration 方法声明
ElementType.PARAMETER Formal parameter declaration 形式参数声明
ElementType.CONSTRUCTOR Constructor declaration 构造函数声明
ElementType.LOCAL_VARIABLE Local variable declaration 局部变量声明
ElementType.ANNOTATION_TYPE Annotation type declaration 注解类型声明
ElementType.PACKAGE Package declaration 包装声明
ElementType.TYPE_PARAMETER Type parameter declarationSince:1.8 类型参数声明自从:1.8
ElementType.TYPE_USE Use of a type Since:1.8 使用类型自从:1.8
ElementType.MODULE Module declaration. Since:9 模块声明。自从:9
  @Target(ElementType.TYPE)——接口、类、枚举、注解
  @Target(ElementType.FIELD)——字段、枚举的常量
  @Target(ElementType.METHOD)——方法
  @Target(ElementType.PARAMETER)——方法参数
  @Target(ElementType.CONSTRUCTOR) ——构造函数
  @Target(ElementType.LOCAL_VARIABLE)——局部变量
  @Target(ElementType.ANNOTATION_TYPE)——注解
  @Target(ElementType.PACKAGE)——包

@Retention:注解的保留位置

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}
参数 原文 注解
RetentionPolicy.SOURCE Annotations are to be discarded by the compiler. 注释将被编译器丢弃。
RetentionPolicy.CLASS Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time. This is the default behavior. 注释将由编译器记录在类文件中,但不需要在运行时由 VM 保留。 这是默认行为。
RetentionPolicy.RUNTIME Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.See Also:reflect.AnnotatedElement 注释将由编译器记录在类文件中,并在运行时由 VM 保留,因此可以反射性地读取它们。反射.AnnotatedElement

RetentionPolicy.SOURCE:这种类型的Annotations只在源代码级别保留,编译时 就会被忽略,在class字节码文件中不包含。
RetentionPolicy.CLASS:这种类型的Annotations编译时被保留,默认的保留策略,在class文件中存在,但JVM将会忽略,运行时无法获得。
RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。

@Document:说明该注解将被包含在javadoc中

@Inherited:说明子类可以继承父类中的该注解

总结:

三个值中SOURCE < CLASS < RUNTIME,即CLASS包含了SOURCE,RUNTIME包含SOURCE、CLASS

反射

下面先看代码

 public static void injectView(Activity activity) {
        //获取class
        Class<? extends Activity> cla = activity.getClass();
        //获取对应class下所有属性
        Field[] fields = cla.getDeclaredFields();
        for (Field field : fields) {
            //判断是否有我们注解
            boolean isEsite = field.isAnnotationPresent(AnnotateFindView.class);
            if (isEsite) {
                AnnotateFindView annotation = field.getAnnotation(AnnotateFindView.class);
                int idResource = annotation.value();
                View view = activity.findViewById(idResource);
                field.setAccessible(true);
                try {
                    field.set(activity, view);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

    }

结合注解就可以省略getIntent

//创建注解
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityValue {
    String value() default "";
}
//反射赋值
public static void injntActivity(Activity activity) {
        Class<? extends Activity> cla = activity.getClass();

        Intent intent = activity.getIntent();
        Bundle extras = intent.getExtras();

        if (extras == null) {
            return;
        }
        Field[] fields = cla.getDeclaredFields();

        for (Field field : fields) {
            boolean isExsit = field.isAnnotationPresent(ActivityValue.class);
            if (isExsit) {
                ActivityValue annotation = field.getAnnotation(ActivityValue.class);
                String key = TextUtils.isEmpty(annotation.value()) ? field.getName() : annotation.value();
                Object obj = extras.get(key);
                Class<?> type = field.getType().getComponentType();
                if (field.getType().isArray() &&null!=type&& Parcelable.class.isAssignableFrom(type)) {
                    Object[] objs = (Object[]) obj;
                    Class<? extends Object[]> clas = (Class<? extends Object[]>) field.getType();
                    obj = Arrays.copyOf(objs, objs.length, clas);
                }

                field.setAccessible(true);
                try {
                    field.set(activity, obj);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }
        }

    }
//跳转
    mainActivity.btnStartIntent.setOnClickListener {
            val vo = UserData().apply {
                age = 2
                name = "小马哥"
                cla = "一年级二班"
            }
            val intent = Intent(this, ContentActivity::class.java).apply {
                putExtra("name", "小明")
                putExtra("age", 1)
                putExtra("vo", vo)
            }
            startActivity(intent)
        }

   

在跳转的ContentActivity 注解以下就可以了

 @ActivityValue
    var name: String? = null;

    @ActivityValue
    var age: Int? = null;

    @ActivityValue(value = "vo")
    var dataVo: UserData? = null;

结合上面就可以扩展个别控件设置背景

相关文章

  • 注解和反射

    注解和反射

  • 一文搞懂反射泛型和反射注解以及通过注解方式写一个BaseDao

    反射泛型和反射注解概括起来就三步: 自定义注解 通过反射获取注解值 使用自定义注解 最终案例 通过自定义注解,将数...

  • 从Java到Kotlin(七)

    反射和注解 目录 1.反射1.1类引用1.2函数引用1.3属性引用 2.注解2.1声明注解2.2构造函数 1.反射...

  • 注解和反射

    (1)注解@Interface(2)@Retention 注解可以保留多长时间:RetentionPolicy....

  • 注解和反射

    注解 什么是注解? 通俗易懂的来说:注释是给人看的,注解可以给机器看。 注解是从JDK5.0引入的新技术。 内置注...

  • 注解和反射

    1、注解的基本理解https://www.jianshu.com/p/9471d6bcf4cf[https://w...

  • 注解和反射

    来源于狂神说笔记

  • 注解和反射

    注解 定义数据 定义数据 输入错误会提示 错误提示 下面解释 @Target:注解的作用目标 参数原文注解Elem...

  • 注解和反射

    https://www.bilibili.com/video/BV1p4411P7V3?p=1[https://w...

  • AS运行Annotation

    AS 运行 Annotation 注解分为运行时注解和编译时注解 运行时注解 原理就是反射和代理(Proxy ) ...

网友评论

      本文标题:注解和反射

      本文链接:https://www.haomeiwen.com/subject/nteunrtx.html