美文网首页iBanana的技术搜集
02.学习java中的@interface

02.学习java中的@interface

作者: 过往入梦 | 来源:发表于2017-11-07 22:37 被阅读0次
    • 注解是Java对于其他语言对Java造成的语言特性压力做出的一种回应,是众多引入到Java SE5中的重要的语言变化之一。

    • Java1.6内置了三种标准注解和四种元注解(元注解专职负责注解其他注解)。

    • 大多数时候我们都是定义自己的注解,并编写自己的处理器来处理它们。


      内置的三种标准注解
      元注解
    • @Target(ElementType.METHOD)

    package java.lang.annotation;
    
    /**
     * @author  Joshua Bloch
     * @since 1.5
     * @jls 9.6.4.1 @Target
     * @jls 4.1 The Kinds of Types and Values
     */
    public enum ElementType {
        /** Class, interface (including annotation type), or enum declaration */
        TYPE,
    
        /** Field declaration (includes enum constants) */
        FIELD,
    
        /** Method declaration */
        METHOD,
    
        /** Formal parameter declaration */
        PARAMETER,
    
        /** Constructor declaration */
        CONSTRUCTOR,
    
        /** Local variable declaration */
        LOCAL_VARIABLE,
    
        /** Annotation type declaration */
        ANNOTATION_TYPE,
    
        /** Package declaration */
        PACKAGE,
    
        /**
         * Type parameter declaration
         *
         * @since 1.8
         */
        TYPE_PARAMETER,
    
        /**
         * Use of a type
         *
         * @since 1.8
         */
        TYPE_USE
    }
    
    • @Retention(RetentionPolicy.RUNTIME)
    package java.lang.annotation;
    
    /**
     * @author  Joshua Bloch
     * @since 1.5
     */
    public enum RetentionPolicy {
        /**
         * Annotations are to be discarded by the compiler.
         */
        SOURCE,
    
        /**
         * Annotations are to be recorded in the class file by the compiler
         * but need not be retained by the VM at run time.  This is the default
         * behavior.
         */
        CLASS,
    
        /**
         * Annotations are to be recorded in the class file by the compiler and
         * retained by the VM at run time, so they may be read reflectively.
         *
         * @see java.lang.reflect.AnnotatedElement
         */
        RUNTIME
    }
    

    定义注解

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

    使用注解

    public class PasswordUtils {
        @UseCase(id = 47, description =
                "Passwords must contain at least one numeric")
        public boolean validatePassword(String password) {
            return (password.matches("\\w*\\d\\w*"));
        }
    
        @UseCase(id = 48)
        public String encryptPassword(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);
        }
    }
    

    编写注解处理器

    public class UseCaseTracker {
        public static void trackUseCases(List<Integer> useCases, Class<?> cl) {
            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<Integer>();
            Collections.addAll(useCases, 47, 48, 49, 50);
            trackUseCases(useCases, PasswordUtils.class);
        }
    }
    
    • 运行结果:
    Found Use Case: 47 Passwords must contain at least one numeric
    Found Use Case: 48 no description
    Found Use Case: 49 New passwords can't equal previously used ones
    Warning: Missing use case-50
    

    几个注意点:

    • 标签@UseCase由UseCase.java定义,其中包括int元素id,以及一个String元素description。

    • 注解元素可用的类型如下(否则编译器报错):

      • 所有基本类型(int, float, boolean等)
      • String
      • Class
      • enum
      • Annotation
      • 以上类型的数组
    • 注解元素必须要么具有默认值,要么在使用注解时提供元素的值。

    • 注解不支持继承。(见Thinking in Java Fourth Edition 20.2.4)

    参考:

    • Thinking in Java Fourth Edition (Bruce Eckel)

    相关文章

      网友评论

        本文标题:02.学习java中的@interface

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