注解Annotation的使用 深入理解Java中的注解 自定义注解 元注解

注解

1. 概念

(1) 注解:用于说明程序,给计算机看的,JDK1.5之后的新特性
使用方式:@注解名称

(2) 注释:用文字描述程序,给编码人员看的

2. 作用

(1) 编写文档
将代码里标识的注解生成doc文档:

① 创建一个类

/**
 * 注解javadoc演示
 * @author 周杰伦  表示此类(文档)作者
 * @version 1.0  表示此类(文档)的版本
 * @since 1.8  表示从JDK1.8之后可以使用此类
 */
public class AnnoDemo1 {
    
    
    /**
     * 计算两数的和
     * @param a 整数
     * @param b 整数
     * @return 两数的和
     */
    public int add(int a, int b ){
    
    
        return a + b;
    }
}

② 对此java文件使用javadoc指令

在这里插入图片描述
③ 打开后的doc文档

在这里插入图片描述

(2) 代码分析:使用反射通过代码中的注解对代码进行分析

(3) 编译检查:通过注解实现编译检查,如@Override

3. 自定义注解

(1) 格式

public @interface 注解名称 {
    
    
// 属性列表;
}

(2) 本质

注解本质上就是一个默认继承Annotation接口的接口,如下:

public interface 自定义注解 extends java.lang.annotation.Annotation {
    
    }

(3) 注解中的属性

注解的属性即接口中的抽象方法

要求:

① 属性的返回值类型:
i. 基本数据类型
ii. 字符串类型String
iii. 枚举
iiii. 注解
iiiii. 以上类型的数组
注意:其他的类型如类类型、void都不可以

② 定义了属性之后,使用时需要给属性赋值

// 自定义注解
public @interface MyAnno {
    
    
    //以下均为省略了abstract关键字的抽象方法

    Person per(); //枚举类型,其中有P1,P2

    MyAnno2 anno2(); // 注解类型,定义另一个注解MyAnno2

    String[] strs(); // 数组类型

    //使用default关键字给属性赋值,表示默认初始值,
    //则使用注解时,可以不给此属性赋值,而使用默认值
    int value() default 15; //基本数据类型
}
// 使用注解
// 数组赋值时,值使用{}包裹,如果数组中只有一个值,可以省略{}
@MyAnno(per = Person.P1, anno2 = @MyAnno2, strs={
    
    "bbb", "ccc"})
public class Worker {
    
     // 自定义类
    //成员变量、属性
}

注意:

  1. 如果注解中只有一个属性且名为value,不论value的类型是什么,则对其赋值时value可省略,直接定义值即可,如@SuppressWarnings(“all”)

  2. 对同一个类或者方法等可以同时使用多个不同的注解

4. 元注解

用于描述注解的注解,在自定义注解的上一行写元注解,有以下四种:

(1) @Target:描述注解能作用的位置
属性:ElementType[] value(); 其中ElementType是枚举类型,常用取值:

  • TYPE 表示可以作用于类上
  • METHOD 表示可以作用于方法上
  • FIELD 表示可以作用于变量上

(2) @Retention:描述注解被保留的阶段
属性:RetentionPolicy value(); 其中RetentionPolicy是枚举类型,取值:

  • RUNTIME 表示当前注解会被保留到class文件中,并被JVM读取到,此值最为常用, 还可取值SOURCE,CLASS

(3) @Documented:描述注解可被抽取到API文档中

(4) @Inherited:描述注解可被继承:如果父类使用了被此元注解描述的注解,则继承此类的子 类即使没有写任何注解,也自动被此注解描述

@Target({
    
    ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
//自定义注解Pro
public @interface Pro {
    
    
    String className();
    String methodName();
}

5. 获取注解的属性值

// 使用上述自定义注解Pro
@Pro(className = "cn.itcast.annotation.Demo1", methodName = "show")
public class ReflectTest {
    
    
    public static void main(String[] args) throws Exception {
    
    
        // 1. 使用该类的字节码文件对象解析注解
        Class<ReflectTest> reflectTestClass = ReflectTest.class;
        // 2. 获取指定的注解对象
        Pro an = reflectTestClass.getAnnotation(Pro.class);
        // 第二步其实就是在内存中生成了一个该注解接口的子类实现对象
        
        /*
            public class ProImpl implements Pro{
                public String className(){
                    return "cn.itcast.annotation.Demo1";
                }
                public String methodName(){
                    return "show";
                }
            }
        */
        
        // 3. 调用注解对象中定义的抽象方法,获取返回值
        String className = an.className();
        String methodName = an.methodName();
        System.out.println(className); //cn.itcast.annotation.Demo1
        System.out.println(methodName); //show
    }
}

注意:使用多个注解时,调用Class对象的空参getAnnotation()方法可以获取所有注解对象,返回 Annoation[]

猜你喜欢

转载自blog.csdn.net/weixin_49343190/article/details/109168408