美文网首页
了解一下Java注解

了解一下Java注解

作者: Zhuang_ET | 来源:发表于2018-06-10 22:08 被阅读0次

    注解为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。
    注解可以用来生成描述符文件,甚至是新的类定义,也有助于减轻编写“样板”代码的负担。
    注解实际上也是一个类,除了@符号的使用外,基本与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<String> prevPasswords, String password) {
            return !prevPasswords.contains(password);
        }
    }
    \\UseCaseTracker.java
    public class UseCaseTracker {
        public static void trackUseCases(List<Integer> 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<Integer> 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注解

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