了解一下Java注解

注解为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。
注解可以用来生成描述符文件,甚至是新的类定义,也有助于减轻编写“样板”代码的负担。
注解实际上也是一个类,除了@符号的使用外,基本与Java固有的语法一致。

标准注解

目前内置了三种标准注解:

  • @Override,表示当前的方法定义将覆盖超类中的方法。如果你不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示。
  • @Deprecated,deprecated: 弃用的意思。如果使用了注解了该注解的元素,编译器会发出警告信息。
  • SuppressWarnings,关闭不当的编译器警告信息。

四种元注解

元注解负责注解其他的注解。

  • @Target:表示该注解可以用于什么地方。ElementType参数包括:CONSTRUCTOR(构造器的声明)/FIELD(域声明)/LOCAL_VARIABLE(方法变量声明)/METHOD(方法声明)/PACKAGE(包声明)/PARAMETER(参数声明)/TYPE(类、接口(包括注解类型)或enum声明)
  • @Retention:表示需要在什么级别保存该注解信息。RetentionPolicy参数包括:SOURCE(注解将被编译器丢弃)/CLASS(注解在class文件中可用,但会被VM丢弃)/RUNTIME(VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息,实际上用的最多的就是这个)
  • @Documented:将此注解包含在Javadoc中,如@author。
  • @Inherited:允许子类继承父类中的注解。

注解的作用

注解是在实际的源代码级别保存所有的信息,而不是某种注释性的文字。通过使用扩展的annotation API,或外部的字节码工具类库,将可以对源代码以及字节码进行检查和操作。实际注解可以理解为一种给机器读的注释。使用注解的过程中,很重要的一个部分就是创建与使用注解处理器,用来读取注解。
在注解中,一般都会包含元素以表示某些值。当分析处理注解时,程序或工具可以利用这些值。
没有元素的注解称为标记注解,就是用来为某些代码打上标记。

注解元素

注解元素可用类型:

  • 所有基本类型
  • String
  • Class
  • enum
  • Annotation
  • 以上类型的数组

如果使用了其他类型,那编译器就会报错。

举个栗子

注解常常与反射机制结合,通过反射在运行期获取注解中的参数。

\\UseCase.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
    public int id();
    public String description() default "no description";
}
\\PasswordUtils.java
public class PasswordUtils {
    @UseCase(id = 47, description = "Passwords must contain at lease on numeric")
    public boolean validatePassword(String password) {
        return (password.matches("\\w*\\d\\w*"));
    }

    @UseCase(id=48)
    public String encrytPassword(String password) {
        return new StringBuilder(password).reverse().toString();
    }

    @UseCase(id=49,description = "New passwords can't equal previously used ones")
    public boolean checkForNewPassword(List prevPasswords, String password) {
        return !prevPasswords.contains(password);
    }
}
\\UseCaseTracker.java
public class UseCaseTracker {
    public static void trackUseCases(List useCases, Class cl) {
        /**
         * cl类通过反射调用getDeclaredMethods()获取类中定义的方法,Method类,
         * 然后通过method就可以调用getAnnotation获取注解对象
         * 通过注解对象就能提取对象里面的元素值了。
         */
        for (Method m : cl.getDeclaredMethods()) {
            UseCase uc = m.getAnnotation(UseCase.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 useCases = new ArrayList<>();
        Collections.addAll(useCases, 47, 48, 49, 50);
        trackUseCases(useCases, PasswordUtils.class);
    }
}
\\Output
Found use Case:48 no description
Found use Case:47 Passwords must contain at lease on numeric
Found use Case:49 New passwords can't equal previously used ones
Warning: Missing use case-50

默认值限制

  • 元素不能有不确定的值,也就是说,元素必须要么具有默认值,要么在使用注解时提供元素的值。
  • 对于非基本类型的元素,无论是在源代码中声明时,或是在注解接口中定义默认值时,都不能以null作为其置。

你可能感兴趣的:(了解一下Java注解)