Java注解原理及实例

2020-06-18  本文已影响0人  Demon先生

1. 什么是注解

Annontation是Java5开始引入的新特征,中文名称叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。Annontation像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。

2. 注解原理

注解本质是一个继承了Annotation 的特殊接口,其具体实现类是Java 运行时生成的动态代理类。而我们通过反射获取注解时,返回的是Java 运行时生成的动态代理对象$Proxy1。通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler 的invoke 方法。该方法会从memberValues 这个Map 中索引出对应的值。而memberValues 的来源是Java 常量池。

3. 元注解及注解处理器类

3.1. 元注解

java.lang.annotation 提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):

3.2. 注解处理器类

java.lang.reflect 包下主要包含一些实现反射功能的工具类,实际上,java.lang.reflect 包所有提供的反射API扩充了读取运行时Annotation信息的能力。当一个Annotation类型被定义为运行时的Annotation后,该注解才能是运行时可见,当class文件被装载时被保存在class文件中的Annotation才会被虚拟机读取。
AnnotatedElement 接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通过反射获取了某个类的AnnotatedElement对象之后,程序就可以调用该对象的如下方法来访问Annotation信息。

4. 自定义注解实例

4.1. 自定义注解规则

4.2. 实例

EventName.java

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventName {

    String value() default "";
    /**
     * 事件类型枚举
     */
    public enum Type{COMMON, MEETING, ACTIVITY };

    /**
     * 事件类型属性
     * @return
     */
    Type eventType() default Type.COMMON;
}

EventBean.java

public class EventBean {
    @EventName("Demon")
    private String name;

    @EventName(eventType = EventName.Type.MEETING)
    private String type;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

TestAnnotation.java

public class TestAnnotation {
    public static void main(String[] args) {
        Field[] fields = EventBean.class.getDeclaredFields();
        for (Field field : fields) {
            EventName eventName = field.getAnnotation(EventName.class);
            System.out.println(eventName.value());
            System.out.println(eventName.eventType());
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读