《Java 编程思想》--第二十章:注解

本文详细介绍了Java注解的定义、作用、定义方法、元素使用、实例演示及注解处理器的创建过程,旨在帮助开发者更好地理解和运用注解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据
  2. 注解可以提供用来完整地描述程序所需的信息,而这些信息是无法用Java来表达的。因此,注解使得我们能够以将由编译器来测试和验证的格式,存储有关程序的额外信息
  3. 几个注解:
    1. @Override:表示当前的方法定义将覆盖超类中的方法
    2. @Deprecated:如果程序员使用了注解为它的元素,那么编译器会发出警告信息
    3. @SuppressWarnings:关闭不当的编译器警告信息
  4. 注解是正真的语言机的概念,一旦构造出来,就像有编译期的类型检查保护。注解是在实际的源代码级别保存所有的信息,而不是某种注释性文字,使得代码更整洁,且便于维护
  5. 定义注解实例:
    1. 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      package annotationTest;
       
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
       
       
      @Target(ElementType.METHOD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface Test{}

    2. 在定义注解时,会需要一些元注解,如@Target和@Retention:
      1. @Targer:用来定义你的注解将应用于什么地方,一个方法或者一个域
      2. @Retention:用来定义该注解是哪一级别可用,在源代码中(SOURCE)、类文件中(CLASS)或者运行时(RUNTIME)
    3. 在注解中一般都会包含一些元素以表示某些值,当分析处理注解时,程序或工具可以利用这些值。注解的元素看起来就像接口的方法,唯一区别是你可以为其指定默认值。没有元素的注解称为标记注解,例如@Test
      1. 包含值的注解UserCase:
        1. 1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          package annotationTest;
           
          import java.lang.annotation.ElementType;
          import java.lang.annotation.Retention;
          import java.lang.annotation.RetentionPolicy;
          import java.lang.annotation.Target;
           
          @Target(ElementType.METHOD)
          @Retention(RetentionPolicy.RUNTIME)
          public @interface UserCase {
              public int id();
           
              public String description() default "no description";
          }

        2. 如上可以看到description元素有一个default值,如果在注解某个方法时没有各处description的值,则该注解的处理器就会使用此元素的默认值”no description“
      2. 包含值的注解UserCase的实例:
        1. 1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          package annotationTest;
           
          import java.util.List;
           
          public class PasswordUtils {
              @UserCase(id = 47, description = "Passwords must contatin at least one numeric")
              public boolean validatePassword(String password) {
                  return (password.matches("\\w*\\d\\w*"));
              }
           
              @UserCase(id = 48)
              public String encryptPassword(String password) {
                  return new StringBuilder(password).reverse().toString();
              }
           
              @UserCase(id = 49, description = "New passwords can't equal previously used ones")
              public boolean checkForNewPassword(List<String> prevPasswords,
                      String password) {
                  return !prevPasswords.contains(password);
              }
           
          }

        2. 注解的元素在使用时表现为名-值对的形式
  6. 元注解:
    1. Java目前只内置了三种标准注解,以及四种元注解。元注解专职负责注解其他的注解:
      1. @Target:表示该注解可以用于什么地方,其ElementType参数包括:
        1. CONSTRUCTOR:构造器的声明
        2. FIELD:域声明(包括enum实例)
        3. LOCAL_VARIABLE:局部变量声明
        4. METHOD:方法声明
        5. PACKAGE:包声明
        6. PARAMETER:参数声明
        7. TYPE:类、接口(包括注解类型)或enum声明
      2. @Retention:表示需要在什么级别保存该注解信息,可选的RetentionPolicy参数有:
        1. SOURCE:注解将被编译器丢弃
        2. CLASS:注解在class文件中可用,但会被VM丢弃
        3. RUNTIME:VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息
      3. @Documented:将此注解包含在Javadoc中
      4. @Inherited:允许子类继承父类中的注解
  7. 编写注解处理器:
    1. 如果没有用来读取注解的工具,那注解不会比注释更有用。使用注解的过程中,很重要的一个部分就是创建与使用注解处理器
    2. 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      package annotationTest;
       
      import java.lang.reflect.Method;
      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.List;
       
      public class UserCaseTracker {
          public static void trackUserCases(List<Integer> useCases, Class<?> cl) {
              for (Method m : cl.getDeclaredMethods()) {
                  UserCase uc = m.getAnnotation(UserCase.class);
                  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, 50);
              trackUserCases(useCases, PasswordUtils.class);
          }
       
      }

    3. 上面这段程序使用到了两个反射方法:getDeclaredMethods()和getAnnotation(),他们都属于AnnotatedElement接口。getAnnotation()方法返回指定类型的注解对象,也就是UseCase
  8. 注解元素可用的类型:
    1. 所有基本类型
    2. String
    3. Class
    4. enum
    5. Annotation
    6. 以上类型的数组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值