java元注解

java元注解

本文涉及以下这些内容,如果不清楚的话,可以看一下,相信会对你有些许帮助。:
1)使用IntelliJ IDEA 2018查看字节码。
2)使用IntelliJ IDEA 2018生成帮助文档

本文主要针对于java8,java8定义了6个标准元注解:@Target,@Retention,@Documented,@Inherited,@Repeatable和@Native。

1.@Target注解。
@Target注解的作用是:描述注解的使用范围(即被修饰的注解可以用在什么地方)。@Target注解用来说明那些被他注解的注解类可修饰的对象范围。

@Target注解源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
   
    ElementType[] value();
    
}

@Target注解的枚举参数:

public enum ElementType {

  	//类,接口,枚举类
    TYPE, 

  	//成员变量,枚举常量
    FIELD, 

	//方法
    METHOD,

	//形式参数
    PARAMETER,

 	//构造方法
    CONSTRUCTOR,

	//局部变量
    LOCAL_VARIABLE,

    //注解
    ANNOTATION_TYPE,

    //包
    PACKAGE,

    //类型参数
    TYPE_PARAMETER,

    //类型使用
    TYPE_USE
}

2.@Retention注解。
@Retention注解的作用是:描述注解保留的时间范围(即:被描述的注解在它所修饰的类中可以被保留到何时)。@Retention注解用来限定那些被他所注解的注解类在注解到其他类上以后,可被保留到何时。

@Retention注解源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
   
    RetentionPolicy value();
    
}

@Retention注解的枚举参数:

public enum RetentionPolicy {
   
   	//源文件保留
    SOURCE,

  	//编译期保留,默认值
    CLASS,

  	//运行期保留,可通过反射去获取注解信息
    RUNTIME
    
}

下面我们举个例子:

注解:

@Retention(RetentionPolicy.SOURCE)
public @interface SourcePolicy {
}

注解:

@Retention(RetentionPolicy.CLASS)
public @interface ClassPolicy {
}

注解:

@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimePolicy {
}

测试类:

public class RetentionTest {

    @SourcePolicy
    public void sourcePolicy(){

    }

    @ClassPolicy
    public void classPolicy(){

    }

    @RuntimePolicy
    public void runtimePolicy(){

    }

}

RetentionPolicy 类的字节码文件中三个方法的部分:

  public void sourcePolicy();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LineNumberTable:
        line 8: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       1     0  this   Lannotation/RetentionTest;

  public void classPolicy();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LineNumberTable:
        line 13: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       1     0  this   Lannotation/RetentionTest;
    RuntimeInvisibleAnnotations:
      0: #14()

  public void runtimePolicy();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LineNumberTable:
        line 18: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       1     0  this   Lannotation/RetentionTest;
    RuntimeVisibleAnnotations:
      0: #17()

根据上面方法的字节码我们可以看出:
1)编译器没有记录sourcePolicy方法的注解信息。
2)编译器使用了RuntimeInvisibleAnnotations属性记录classPolicy方法的注解信息,使用RuntimeVisibleAnnotations属性记录runtimePolicy方法的注解信息。

3.Documented注解。
Documented注解的作用是:描述在使用javadoc工具为类生成帮助文档时是否要保留其注解信息。

Documented注解源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

下面我们举个例子:

注解:

@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyDocumentedAnnotation {

}

测试类:

@MyDocumentedAnnotation
public class MyDocumentedTest {

    @MyDocumentedAnnotation
    @Override
    public String toString(){
        return this.toString();
    }

}

查看生成的帮助文档:

java元注解_第1张图片
java元注解_第2张图片

接下来把@Documented注解去掉,重新生成帮助文档:
java元注解_第3张图片

java元注解_第4张图片

由此我们可以看出@Documented注解的作用。

4.Inherited注解。
Inherited注解的作用是:使被他修饰的注解具有继承性(如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解。)

下面我们举个例子:

注解:

@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyInheritedAnnotation {

    public String name() default "pengjunlee";

}

父类:

@MyInheritedAnnotation(name = "parent")
public class Parent {
}

子类:

public class Child extends Parent {

    public static void main(String[] args) {
        Class<Child> child = Child.class;
        MyInheritedAnnotation annotation = child.getAnnotation(MyInheritedAnnotation.class);
        System.out.println(annotation.name());
    }

}

输出:
parent

5.@Repeatable注解。
@Repeatable注解的作用是:用于声明标记的注解为可重复类型注解,可以在同一个地方多次使用。

@Repeatable 注解源码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    
    Class<? extends Annotation> value();
    
}

下面我们举个例子:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyRepeatableAnnotation {

    RepeatableAnnotationTest[] value();

}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyRepeatableAnnotation.class)
public @interface RepeatableAnnotationTest {

    String key();

    String value();

}
@RepeatableAnnotationTest(key = "aa",value = "11")
@RepeatableAnnotationTest(key = "bb",value = "22")
public class RepeatableTest {

    public static void main(String[] args) {
        RepeatableAnnotationTest[] annotation = RepeatableTest.class.getAnnotation(MyRepeatableAnnotation.class).value();
        for (RepeatableAnnotationTest a : annotation) {
            System.out.println(a);
        }
    }

}

输出:
@annotation.RepeatableAnnotationTest(key=aa, value=11)
@annotation.RepeatableAnnotationTest(key=bb, value=22)

6.@Native注解。
@Native注解修饰成员变量,则表示这个变量可以被本地代码引用,常常被代码生成工具使用。对于@Native注解不常使用,了解即可。

你可能感兴趣的:(java方面,java,intellij-idea,开发语言)