美文网首页
JAVA中的注解

JAVA中的注解

作者: Jon_Snow09 | 来源:发表于2018-08-12 23:12 被阅读0次

    abstract

    • 什么是java中的注解
    • 注解的定义
    • 自定义一个注解

    什么是java中的注解

    注解提供了一种安全的类似注释的机制.用来将 任何的信息或者元数据 (metadata)与程序元素( 类,方法,成员变量等 )进行关联,为程序的元素加上更加直观的说明,这些说明信息与程序的业务逻辑无关,是由 指定的工具或框架 来实现的.Annotation像修饰符一样,应用于包,类型构造方法,方法,成员变量,参数,及本地变量的声明语句中.

    注解的定义

    先看下面的例子

    //下面两个是必须的元注解,分别确定了这个注解的作用对象(类的方法)和生命周期(这个注解会被保存在class文件中,并且直到运行时也不会被丢弃)
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface BindView {
        //此处定义了注解可以接受一个数据类型为int的元数据
        int value();
    }
    

    所以,定义一个注解分为三步

    1. 跟类(class),接口(interface),枚举(enum)一样,注解的定义有自己的关键字(@interface)
    2. 定义注解时需要元注解的定义(之前已经提到过了,注解作用的对象是类,方法,成员变量等,那么元注解作用的对象就是注解本身),一般有下面几个元注解
    • @Target 用来标注注解的作用对象,是类,方法,还是成员变量
    • @Retention 用来标注注解的生命周期,有三种 1.RetentionPolicy.SOURCE,表示这个注解只出现在源码中,编译时会被编译器抛弃 2.RetentionPolicy.CLASS,这种是注解的默认状态,表示这个注解会被保存到class文件中,但是到了runtime就会被抛弃 3.RetentionPolicy.RUNTIME,这表示注解会保留到运行时
    • @Documented 它的作用是能够将注解中的元素包含到Javadoc中去
    • @Inherited Inherited 是指继承,@Inherited 定义了一个注释与子类的关系。如果一个超类带有 @Inherited 注解,那么对于该超类,它的子类如果没有被任何注解应用的话,那么这个子类就继承了超类的注解
    • @Repeatable 用这个元注解修饰之后,注解可以重复赋值

    3.最后,需要在注解内部定义方法,接收使用注解时在注解后面的赋值

    自定义一个注解

    现在我们举个栗子,自定义一个简单的butterknife注解,实现两个功能,一是直接注解成员变量得到控件的对象,而是直接成员方法得到控件的点击事件

    获取控件引用的注解

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface BindClick {
        int value();
    }
    

    绑定点击事件的注解

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    public @interface BindView {
        //此处定义了注解可以接受一个数据类型为int的元数据
        int value();
    }
    

    最重要的一个类,读取这两个注解的值,并且将其实现的框架类,通过注入一个activity对象,就可以解析所有activity里面的注解,并完成相应的功能

    public class ButterKnife {
        public static void inject(Activity activity) {
            Class<? extends Activity> clazz = activity.getClass();
    
            Field[] declaredFields = clazz.getDeclaredFields();
            for (Field field : declaredFields) {
                if (field.isAnnotationPresent(BindView.class)) {
                    BindView annotation = field.getAnnotation(BindView.class);
                    int resId = annotation.value();
                    field.setAccessible(true);
                    try {
                        field.set(activity, activity.findViewById(resId));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
    
            Method[] declaredMethods = clazz.getDeclaredMethods();
            for (Method method : declaredMethods) {
                if (method.isAnnotationPresent(BindClick.class)) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        BindClick declaredAnnotation = method.getDeclaredAnnotation(BindClick.class);
                        int resId = declaredAnnotation.value();
                        method.setAccessible(true);
                        View viewById = activity.findViewById(resId);
                        viewById.setOnClickListener(v -> {
                            try {
                                method.invoke(activity, v);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        });
                    }
                }
            }
        }
    }
    

    最后一步,在activity中编写相应的注解,并且调用ButterKnife.inject(this)就可以了

    public class MainActivity extends AppCompatActivity {
        @BindView(R.id.tv_title)
        TextView tvTitle;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ButterKnife.inject(this);
            tvTitle.setText(getResources().getString(R.string.app_name));
        }
    
        @BindClick(R.id.tv_title)
        public void onTitleClick(View view) {
            Toast.makeText(this, getResources().getString(R.string.app_name), Toast.LENGTH_SHORT).show();
        }
    }
    

    相关文章

      网友评论

          本文标题:JAVA中的注解

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