java入门篇10 --- 注解

从JVM的角度看,注解本身对代码逻辑没有任何影响,如何使用注解完全由工具决定。

Java的注解可以分为三类:

第一类是由编译器使用的注解,例如:

  • @Override:让编译器检查该方法是否正确地实现了覆写;
  • @SuppressWarnings:告诉编译器忽略此处代码产生的警告。

这类注解不会被编译进入.class文件,它们在编译后就被编译器扔掉了。

第二类是由工具处理.class文件使用的注解,比如有些工具会在加载class的时候,对class做动态修改,实现一些特殊的功能。这类注解会被编译进入.class文件,但加载结束后并不会存在于内存中。这类注解只被一些底层库使用,一般我们不必自己处理。

第三类是在程序运行期能够读取的注解,它们在加载后一直存在于JVM中,这也是最常用的注解。例如,一个配置了@PostConstruct的方法会在调用构造方法后自动被调用(这是Java代码读取该注解实现的功能,JVM并不会识别该注解)。

java语言中使用@interface来定义注解,我们自定义注解的时候,一定要记得加上@Target,里面的参数根据情况添加,ElementType.METHOD, ElementType.FIELD ...

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
 

@Retention这个愿注解可以定义注解的生命周期, 默认情况为仅class文件

  • 仅编译期:RetentionPolicy.SOURCE
  • 仅class文件:RetentionPolicy.CLASS
  • 运行期:RetentionPolicy.RUNTIME

接下来看一下自定义的注解如何使用,这个可以在我们做单元测试时使用

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;

// 把最常用的参数定义为value(),推荐所有参数都尽量设置默认值。
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno {
    int min() default 0;

    int max() default 20;
}

class Person {
    @MyAnno(min = 10, max = 80)
    public int age;
}

public class HelloWorld {
    public static void main(String[] args) throws Exception {
        Person p = new Person();
        Person p1 = new Person();
        p.age = 100;
        p1.age = 15;
        Field f = Person.class.getField("age");
        int s = (Integer) f.get(p);
        int s1 = (Integer) f.get(p1);
        MyAnno anno = f.getAnnotation(MyAnno.class);
        System.out.println(s < anno.max() && s > anno.min());  // false
        System.out.println(s1 < anno.max() && s1 > anno.min());  // true
    }
}

你可能感兴趣的:(java入门篇10 --- 注解)