Java 注解

目录

 

1.注解

2.使用注解

3.元注解

@Documented

@Retention

@Target

@Inherited


1.注解

注解就相当于一个标签,在这个标签里面可以存储一些值,在需要的时候就可以取出标签内的值使用。

2.使用注解

声明一个注解的时候, 里面的属性只能为public或者默认不写.不能为 protected 或 private.

@Retention(RetentionPolicy.RUNTIME) // 设置在运行时可以获取到注解属性
public @interface TestAnnotation1 {
    // 如果只有一个value可以直接赋值,否则使用value=...
    String value();

    // 声明一个数组
    String[] args();

    // num属性的默认值为1
    int num() default 1;
}
@TestAnnotation1(args = { "参数1", "参数2" }, value = "AnnotationTest", num = 123)
public class AnnotationTest {
    // 给数组赋值时要用大括号括起来,参数有默认值就可以不用赋值,直接使用默认值
    @TestAnnotation1(value = "value", args = { "123", "789" })
    public void test() {

    }

    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
        // 获取注解信息
        /**
         * 得到一个类的字节码有三种方式: 1.类名.class 2.类的实例.getClass() 3.Class.forName()
         */
        // 获取AnnotationTest的类型信息对象
        Class<?> class1 = AnnotationTest.class;
        // 获取AnnotationTest类上的注解
        TestAnnotation1 classAnnotation = class1.getAnnotation(TestAnnotation1.class);// 获取类上的注解信息
        //获取注解信息
        System.out.println(classAnnotation.num());
        System.out.println(classAnnotation.value());
        System.out.println(Arrays.toString(classAnnotation.args()));

        //通过AnnotationTest的类信息对象获取类里面的方法
        Method method = class1.getMethod("test");
        // 获取方法上的注解
        TestAnnotation1 methodAnnotation = method.getAnnotation(TestAnnotation1.class);
        // method.getAnnotations();//获取所有的注解
        System.out.println(methodAnnotation.num());
        System.out.println(methodAnnotation.value());
        System.out.println(Arrays.toString(methodAnnotation.args()));
    }
}

3.元注解

元注解就是使用在注解上的注解.

@Documented

使用了@Documented注解后, 在生成javadoc时编译器就能够将注解中的元素包含到 Javadoc 中去。

@Retention

当 @Retention 使用到一个注解上的时候,它说明了这个注解的的存活时间。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

@Retention注解中也只有一个枚举类数组RetentionPolicy属性

  • RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时(class文件)它将被丢弃(也就是说在class文件中找不到该注解)
  • RetentionPolicy.CLASS 注解只被保留到编译(class文件)的时候,它并不会被加载到 JVM 中。(在class文件中存在该注解,但是在运行时无法获取该注解的属性值)
  • RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,在程序运行时可以获取到它们。

如果在自定义一个注解的时候没有使用@Retention指定该注解的存活时间, 那么将默认为 RetentionPolicy.CLASS

@Target

@Target 指定了注解运用的地方, 如果在声明类时只指定了在方法上能够使用, 那么在其他地方使用就会报错

下面时@Target 注解的源代码

@Documented // 能够将注解中的元素包含到 Javadoc 中去。
@Retention(RetentionPolicy.RUNTIME)  // 指定@Target注解的的存活时间
@Target(ElementType.ANNOTATION_TYPE) // 指定@Target注解只能在注解上使用
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();
}

@Target注解只有一个ElementType数组属性, ElementType为枚举类型

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,//可以给一个类型进行注解,比如类、接口、枚举

    /** Field declaration (includes enum constants) */
    FIELD,//可以给属性进行注解

    /** Method declaration */
    METHOD,//可以给方法进行注解

    /** Formal parameter declaration */
    PARAMETER,//可以给一个方法内的参数进行注解

    /** Constructor declaration */
    CONSTRUCTOR,//可以给构造方法进行注解

    /** Local variable declaration */
    LOCAL_VARIABLE,//可以给局部变量进行注解

    /** Annotation type declaration */
    ANNOTATION_TYPE,//可以给一个注解进行注解

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}
//该注解只能在类(类,接口,枚举类)和方法上使用
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@interface TestAnnotation1 {
    // 如果只有一个value可以直接赋值,否则使用value=...
    String value();

    // 声明一个数组
    String[] args();

    // num属性的默认值为1
    int num() default 1;
}

@Inherited

如果在自定义注解 A 的时候使用了@Inherited , 然后使用 A 注解类 B , 这时候类 B 有一个注解 A , 如果另外一个类 C 继承了 B , 那么类 C 也会有一个注解 A.(如果在自定义注解 A 的时候没有使用@Inherited , 那么类 C 就不会有注解 A)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值