运行时注解

运行时注解

运行时注解使用 RetentionPolicy.RUNTIME 修饰,注解会被编译器记录在java和class文件中并被虚拟机保留到运行时,可以通过反射处理。由于使用 RetentionPolicy.RUNTIME 修饰代码发生在运行阶段使用反射,所以性能上有所损耗。

一、获取注解
/*
* 获取特定注解
*/
public <T extends Annotation> T getAnnotation(Class<T> annotationClass);

/*
* 指定注解是否存在该元素上
*/
public boolean isAnnotationPresent(Class<? extends Annotation> annotationType);

/*
* 返回类中所有指定注解
* 分别表示获取所有指定的public元素,包括继承的公有方法 和 获取所有本类中的所有指定元素
*/
xxx[] annotations = clazz.getxxxs();
xxx[] annotations = clazz.getDeclaredxxxs();
eg:
    /**
     * 获取类
     */
    public static void parseTypeAnnotation() {
        Class clazz = UserAnnotation.class;

        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation a : annotations) {
            MethodInfo annotation = (MethodInfo) a;
            MLog.log("class = " + clazz.getName() + " | id = "
                    + annotation.id() + " | name = " + annotation.name());
        }
    }
    /**
     * 获取构造方法
     */
    public static void parseConstructAnnotation() {
        Constructor[] constructors = UserAnnotation.class.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            boolean hasAnnotation = constructor.isAnnotationPresent(MethodInfo.class);
            if (hasAnnotation) {
                MethodInfo annotation = (MethodInfo) constructor.getAnnotation(MethodInfo.class);
                MLog.log("constructor = " + constructor.getName() + " | id = "
                        + annotation.id() + " | name = " + annotation.name());
            }
        }
    }
    /**
     * 获取方法
     */
    public static void parseMethodAnnotation() {
        Method[] methods = UserAnnotation.class.getDeclaredMethods();
        for (Method method : methods) {
            boolean hasAnnotation = method.isAnnotationPresent(MethodInfo.class);
            if (hasAnnotation) {
                MethodInfo annotation = method.getAnnotation(MethodInfo.class);
                MLog.log("method = " + method.getName() + " | id = "
                        + annotation.id() + " | name = " + annotation.name());
            }
        }
    }
    /**
     * 获取属性
     */
    public static void parseFieldAnnotation() {
        Field[] fields = UserAnnotation.class.getDeclaredFields();
        for (Field field : fields) {
            boolean hasAnnotation = field.isAnnotationPresent(MethodInfo.class);
            if (hasAnnotation) {
                MethodInfo annotation = field.getAnnotation(MethodInfo.class);
                MLog.log("field = " + field.getName() + " | id = "
                        + annotation.id() + " | name = " + annotation.name());
            }
        }
    }
二、使用运行时注解实现简单的findViewById功能
  • 自定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface IdInject {
    int value();
}
  • 解析注解,都是反射的知识了
    public static void inject(Activity activity) {
        Class cls = activity.getClass();
        Field[] fields = cls.getDeclaredFields(); // 能获取自己声明的各种字段,包括public,protected,private
        if (fields != null) {
            for (Field field : fields) {
                boolean hasAnnotation = field.isAnnotationPresent(IdInject.class);
                if (hasAnnotation) {
                    IdInject inject = field.getAnnotation(IdInject.class);
                    View view = activity.findViewById(inject.value());
                    if (view != null) {
                        field.setAccessible(true); //能获取自己声明的各种字段,包括public,protected,private
                        try {
                            field.set(activity, view);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
  • 使用

在属性声明处添加注解,括号中为TextView中的id

@IdInject(R.id.text)
private TextView text; // 通过反射,故可以用private修饰

在使用前调用下面方法,动态为属性赋值

IdInjectProcessor.inject(this);

这样 text 就已经可以使用了,不用再写 findViewById 了。但是因为是运行时注解,性能不好,不建议使用运行时注解实现 findViewById 功能,可以看后面文章使用编译时注解。

eg: AnnotationPractice-branch2

下篇文章介绍编译时注解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值