Java编程思想笔记七:注解

作者: 红薯的Java私房菜 | 来源:发表于2022-07-27 21:53 被阅读0次
7.注解.png

注解(也称元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。

Java SE5 内置了三种注解,定义在 java.lang 中:

  • @Override,表示当前方法定义将覆盖基类中的方法,如果方法签名与被覆盖的方法不对应,编译器会报错;
  • @Deprecated,表示当前元素即将弃用,程序中使用它时编译器会告警;
  • @SuppressWarnnings,关闭不当的编译器警告信息。

1.使用注解

使用注解很简单,只需在要使用注解的元素前加 @ 后面跟要加的注解即可。例如使用 @Test 注解修饰 testExecute() 方法让其可运行:

public class TestTable {
    @Test
    void testExecute() { System.out.println("Executing..."); }
}

2.定义注解

我们除了可以使用 Java 内置的注解,还可以自定义注解。Java 提供了四种元注解专职负责注解其他的注解:

注解 描述
@Target 用来约束注解可以应用的地方(如方法、类或字段),可选的 ElementType 参数包括:
CONSTRUCTOR:构造函数声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或 enum 声明
TYPE_PARAMETER:Java8新增,类型参数
TYPE_USE:Java8新增,标注任意类型(不包括class)
@Retention 表示注解信息的保存级别,可选的 RetentionPolicy 参数包括:
SOURCE:注解将被编译器丢弃。
CLASS:注解在class文件中可用,但会被VM丢弃。
VM将在运行期也会保留注解,可通过反射机制读取注解的信息。
@Decumented 将此注解包含在 Javadoc 中
@Inherited 允许子类继承父类中的注解
@Repeatable Java 8新增的元注解,表示在同一个位置重复相同的注解

我们可以自定义一个 @UseCase 注解:

//: annotations/UseCase.java
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
    public int id();
    public String description() default "no description";
}

定义 PasswordUtils 类使用 @UseCase 注解:

public class PasswordUtils {
    @UseCase(id = 47, description = "Password must be number.")
    public boolean validatePassword(String password) {
        return (password.matches("/^[0-9]*$/g"));
    }
}

使用自定义注解时需要注意 4 点

  1. 注解元素可用类型有限
    @UseCase 注解包含了两个元素:int 类型的 id 和 String 类型的 description。注解元素只支持一下几种类型:
  • 所有基本类型(int,float,boolean 等)
  • String
  • Class
  • enum
  • Annotation (注解嵌套)
  • 上述类型的数组
    如果你使用了其它类型,编译器会报错。
  1. 使用注解时注解元素必须有默认值
    注解的所有元素要么具有默认值,要么在使用时提供元素的值。此外,对于非基本类型的元素,无论是在源代码中声明时,还是在注解接口中定义默认值时,都不能以 null 作为元素的值。

  2. 使用快捷方式设置元素的默认值
    当注解中只有一个元素需要赋值时,无需使用元素名-值的这种语法,只需在括号内给出该元素的值即可。例如,PasswordUtils 中使用注解 @UseCase 时,description 用默认值即可,那只有 id 需要赋值,则可以使用快捷方式:

  3. 注解不支持继承,不能使用 extends 来继承某个 @interface

public class PasswordUtils {
    @UseCase(47)    // 快捷方式赋值:id = 47,description 使用默认值
    public boolean validatePassword(String password) {
        return (password.matches("/^[0-9]*$/g"));
    }
}

3.编写注解处理器

大多时候,我们除了自定义注解,还需要编写自己的注解处理器来处理它们,这就需要用到反射机制。我们写一个简单的注解处理器来处理 PasswordUtils 类中的 @UseCase 注解:

public class UseCaseTracker {
    public static void trackUseCases(List<Integer> useCases, Class<?> cl) {
        for (Method m : cl.getDeclaredMethods()) {          // 反射:获取对象的所有方法
            UseCase uc = m.getAnnotation(UseCase.class)     // 反射:获取方法上指定的注解(@UseCase)
            if (uc != null) {
                System.out.println("Found Use Case:" + uc.id() + " " + uc.description())
                useCases.remove(new Integer(uc.id()));
            }
        }
        for (int i : useCases) {
            System.out.println("Warning: Missing use case-" + i);
        }
    }

    public static void main(String[] args) {
        List<Integer> useCases = new ArrayList<Integer>();
        Collections.addAll(useCases, 47, 48, 49);
        trackUseCases(useCases, PasswordUtils.class);
    }
}

4.使用 apt 处理注解

注解处理工具 apt 是 Sun 为了帮助注解的处理过程而提供的工具。

与 javac 一样,apt 被设计为操作 Java 源文件,而不是编译后的类。apt 会在处理完源文件后编译它们,如果在系统构建过程中自动创建了新的源文件,该文件会在新一轮的注解处理过程中接受检查,apt 会一轮一轮地处理,直到不再有新的源文件产生为止,然后它再编译所有文件。

我们自定义的每个注解都需要自己的处理器,apt 工具能够很容易地将多个注解处理器组合在一起。这样,我们就可以指定多个要处理的类,比自己去遍历所有的类文件简单的多。

通过使用 AnnotationProcessorFactory apt 能够为每一个它发现的注解生成一个正确的注解处理器。在使用 apt 生成注解处理器时,无法使用 Java 的反射机制,因为我们操作的时源代码,而不是编译后的类。使用 mirror API 可以解决这个问题,它使我们能够在未经编译的源代码中查看方法、域以及类型。

相关文章

  • Java编程思想笔记七:注解

    注解(也称元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。 ...

  • Java注解学习总结(脑图)

    注解的提取测试:定义注解: 测试注解提取: 参考:《Java编程思想》java注解

  • Java——注解(Annotation)入门学习

    学习资料: Java编程思想 ——第20章 公共技术点之 Java 注解 Annotation 注解(Annota...

  • 《java编程思想 注解》学习笔记

    概念 标记注解 An annotation without any elements is called a ma...

  • Java编程思想笔记20.注解

    点击进入我的博客 注解为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据...

  • 2018-02-28Java注解

    参考:《java编程思想》 一。注解分为3类: 1.标准注解(3个): @Override:标识该方法继承自超类。...

  • Java编程思想(十九) 注解

    Java内置三种注解: @Override 表示当前的方法定义将覆盖超类中的方法。 @Deprecated 如果使...

  • 2021-09-15 JAVA编程思想

    Java编程思想重点笔记(Java开发必看)[https://www.cnblogs.com/softwareof...

  • Java注解——初识

    Annotation(注解)这个新特性是在 java1.5 之后被引入的。在 java编程思想 中是这么说的: 注...

  • Java annotation,注解

    注解 Java编程思想中这样定义注解:注解被称为元数据,为我们在代码中添加信息提供了一种形式化的方法。使我们在稍后...

网友评论

    本文标题:Java编程思想笔记七:注解

    本文链接:https://www.haomeiwen.com/subject/zkqtwrtx.html