java - 注解

2017-10-19  本文已影响35人  小菜_charry

1. 元注解

元注解:用在注解上的注解,java1.5后添加的4个元注解:

在java1.8又添加了两个注解:

先说明下这几个注解.

@Target 修饰的对象范围

取值(ElementType)有:

当注解类型声明中没有@Target元注解,则默认为可适用所有的程序元素。

@Retention 注解保留到哪个时期(生命周期)

取值(RetentionPoicy)有:

默认CLASS,可以看下源码中提解释:

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
}

@Documented 标志可文档化

被标注的程序成员的公共API,因此可以被例如javadoc此类的工具被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化

@Inherited 将注解内容传递到子类

若是方法被重写则得不到父类方法中的注解内容,关于该方法所有的内容都被重新定义了.

在类上的注解会被传递该子类,方法也可以但重写了则不会在传递给子类
再次捋清楚下:

2.常见的Java注解

我们平时直接使用java提供几个注解:@Override @Deprecated @SuppressWarnings @FunctionalInterface,下面逐个看下其定义

3. 自定义注解

Annotaion不影响程序代码的执行,无论增加、删除Annotation,代码都始终如一地执行。
也就是说:如果我们不去解析注解,它就没什么作用和影响.
在 java.lang.Class 中末尾有4个涉及的解析注解的方法:

除此之外还有写注意事项:

4. 实践自定义注解

首先看下接下来要实现的相关类:


类结构

FruitName 水果名称

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

    String value() default "";

}

FruitColor 水果颜色

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FruitColor {

    public enum Color {
        BLUE("蓝色"), RED("红色"), GREEN("绿色");

        private String name;

        public String getName() {
            return name;
        }

        Color(String name) {
            this.name = name;
        }
    }

    Color value() default Color.GREEN;
}

FruitProvider 供应商信息

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

    int id() default 1;

    String address() default "";

    String providerName() default "";

}

接下来到使用类了

Apple 使用注解

public class Apple {

    @FruitName("苹果")
    public String name;

    @FruitColor(FruitColor.Color.GREEN)
    public String color;

    @FruitProvider(id=1001,address = "美国硅谷",providerName = "苹果公司")
    public String  provider;

}

FruitAnnotationParser 注解解析类

public class FruitAnnotationParser {

    public static void parse() {
        Field[] fields = Apple.class.getDeclaredFields();

        for (Field field : fields) {
            if (field.isAnnotationPresent(FruitName.class)) {
                FruitName fruitName = field.getAnnotation(FruitName.class);
                String value = fruitName.value();
                System.out.println(value);

            } else if (field.isAnnotationPresent(FruitColor.class)) {
                FruitColor fruitColor = field.getAnnotation(FruitColor.class);
                FruitColor.Color color = fruitColor.value();
                System.out.println(color.getName());

            } else if (field.isAnnotationPresent(FruitProvider.class)) {
                FruitProvider provider = field.getAnnotation(FruitProvider.class);
                String address = provider.address();
                int id = provider.id();
                String providerName = provider.providerName();
                System.out.println(String.format("providerName:%s id:%d address:%s", providerName, id, address));

            }
            
        }
    }
}

测试

public class FruitTest {

    public static void main(String[] args) {
        FruitAnnotationParser.parse();
    }

}

输出:

苹果
绿色
providerName:苹果公司 id:1001 address:美国硅谷

注解理解之后使用起来还是比较简单的,解析注解的套路就那么4个,解析的过程都差不多.

上一篇 下一篇

猜你喜欢

热点阅读