3
笔记来源:IMOOC Java注解

注解的分类

  • 按照运行机制分

    • 源码注解:注解只在源码中存在,编译成 .class 文件就不存在了
    • 编译时注解:注解在源码和 .class 文件中都存在
    • 运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解
  • 按照来源分

    • 来自JDK的注解
    • 来自第三方的注解
    • 我们自己定义的注解
  • 元注解:给注解进行注解

自定义注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description { // 使用 @interface 关键字定义注解
    String desc(); // 成员以无参无异常方式声明
    String author();
    int age() default 18; // 可以用 default 为成员指定一个默认值
}

自定义注解的语法要求

  • 使用 @interface 关键字定义注解
  • 成员以无参无异常方式声明
  • 可以用 default 为成员指定一个默认值
  • 成员类型是受限的,合法的类型包括原始类型及 StringClassAnnotationEnumeration
  • 如果注解只有一个成员,则成员名必须取名为 value(),在使用时可以忽略成员名和赋值号 =
  • 注解类可以没有成员,没有成员的注解称为标识注解

注解的注解(元注解)

  • @Target:注解的作用域

    • 包、类、字段、方法、方法的参数、局部变量
  • @Retention:注解的生命周期

    • SOURCE:只在源码显示,编译时会丢弃
    • CLASS:编译时会记录到 class 中,运行时忽略
    • RUNTIME:运行时存在,可以通过反射读取
  • @Inherited:标识性注解,允许子类继承(接口实现是没有任何作用的,只会继承类注解,不会继承其他如方法的注解)
  • @Document:生成 javadoc 时会包含注解

使用自定义注解

@Description(desc = "I am eyeColor", author = "Mooc boy", age = 18)
public String eyeColor() {
    return "red";
}

@<注解名>(<成员名1> = <成员值1>, <成员名2> = <成员值2>, ...)

解析注解

概念:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。

@Description(desc = "I am Example", author = "Mooc boy", age = 18)
public class Example {
    @Description(desc = "I am eyeColor", author = "Mooc boy", age = 18)
    public String eyeColor() {
        return "red";
    }
}
try {
    // 1. 使用类加载器加载类
    Class c - Class.forName("Example");
    // 2. 找到类上面的注解
    boolean isExist = c.isAnnotationPresent(Description.class);
    if (isExist) {
        // 3. 拿到注解实例
        Description d = (Description) c.getAnnotation(Description.class);
        System.out.println(d.desc());
    }
    Method[] ms = c.getMethods();
    // 4-1. 找到方法上的注解
    for (Method m: ms) {
        boolean isMExist = m.isAnnotationPresent(Description.class);
        if (isMExist) {
            Description d = (Description) c.getAnnotation(Description.class);
            System.out.println(d.desc());
        }
    }
    // 4-2. 找到方法上的注解
    for (Method m: ms) {
        Annotation[] as = m.getAnnotations();
        for (Annotation a: as) {
            Description d = (Description) a;
            System.out.println(d.desc());
        }
    }
} catch (Exception e) {
    e.printStackTrace();
}

总结

  1. 认识注解
  2. 注解的作用范围 @Target 和生命周期 @Retention

    • 作用范围:包、类、字段、方法、方法的参数、局部变量
    • 生命周期:源文件、编译时、运行时
  3. 能读懂注解
  4. 能在实际项目中用注解解决问题,并能自定义注解

gcusky
135 声望6 粉丝

目标