zoukankan      html  css  js  c++  java
  • 注解

    注解是 Java 5 所引入的众多语言变化之一。它们提供了 Java 无法表达的但是你需要完整表述程序所需的信息。因此,注解使得我们可以以编译器验证的格式存储程序的额外信息。注解可以生成描述符文件,甚至是新的类定义,并且有助于减轻编写“样板”代码的负担。通过使用注解,你可以将元数据保存在 Java 源代码中。并拥有如下有下优势:简单易读的代码,编译器类型检查,使用 annotation API 为自己的注解构造处理工具。即使 Java 定义了一些类型的元数据,但是一般来说注解类型的添加和如何使用完全取决于你。

    • @Override:表示当前的方法定义将覆盖基类的方法。如果你不小心拼写错误,或者方法签名被错误拼写的时候,编译器就会发出错误提示。
    • @Deprecated:如果使用该注解的元素被调用,编译器就会发出警告信息。
    • @SuppressWarnings:关闭不当的编译器警告信息。
    • @SafeVarargs:在 Java 7 中加入用于禁止对具有泛型varargs参数的方法或构造函数的调用方发出警告。
    • @FunctionalInterface:Java 8 中加入用于表示类型声明为函数式接口

    自定义注解例子

    // annotations/UseCase.java
    import java.lang.annotation.*;
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface UseCase {
        int id();
        String description() default "no description";
    }
    // annotations/PasswordUtils.java
    import java.util.*;
    public class PasswordUtils {
        @UseCase(id = 47, description =
                "Passwords must contain at least one numeric")
        public boolean validatePassword(String passwd) {
            return (passwd.matches("\w*\d\w*"));
        }
        @UseCase(id = 48)
        public String encryptPassword(String passwd) {
            return new StringBuilder(passwd)
                    .reverse().toString();
        }
        @UseCase(id = 49, description =
                "New passwords can't equal previously used ones")
        public boolean checkForNewPassword(
                List<String> prevPasswords, String passwd) {
            return !prevPasswords.contains(passwd);
        }
    }
    // annotations/PasswordUtils.java
    import java.util.*;
    public class PasswordUtils {
        @UseCase(id = 47, description =
                "Passwords must contain at least one numeric")
        public boolean validatePassword(String passwd) {
            return (passwd.matches("\w*\d\w*"));
        }
        @UseCase(id = 48)
        public String encryptPassword(String passwd) {
            return new StringBuilder(passwd)
                    .reverse().toString();
        }
        @UseCase(id = 49, description =
                "New passwords can't equal previously used ones")
        public boolean checkForNewPassword(
                List<String> prevPasswords, String passwd) {
            return !prevPasswords.contains(passwd);
        }
    }
    // annotations/UseCaseTracker.java
    import java.util.*;
    import java.util.stream.*;
    import java.lang.reflect.*;
    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(Integer.valueOf(uc.id()));
                }
            }
            useCases.forEach(i ->
                    System.out.println("Missing use case " + i));
        }
        public static void main(String[] args) {
            List<Integer> useCases = IntStream.range(47, 51)
                    .boxed().collect(Collectors.toList());
            trackUseCases(useCases, PasswordUtils.class);
        }
    }

    输出

    Found Use Case 48
    no description
    Found Use Case 47
    Passwords must contain at least one numeric
    Found Use Case 49
    New passwords can't equal previously used ones
    Missing use case 50

    注解的元素在使用时表现为 名-值 对的形式,并且需要放置在 @UseCase 声明之后的括号内。在 encryptPassword() 方法的注解中,并没有给出 description 的默认值,所以在 @interface UseCase 的注解处理器分析处理这个类的时候会使用该元素的默认值。

    这个程序用了两个反射的方法:getDeclaredMethods() 和 getAnnotation(),它们都属于 AnnotatedElement 接口(Class,Method 与 Field 类都实现了该接口)。getAnnotation() 方法返回指定类型的注解对象,在本例中就是 “UseCase”。如果被注解的方法上没有该类型的注解,返回值就为 null。我们通过调用 id() 和 description() 方法来提取元素值。注意 encryptPassword() 方法在注解的时候没有指定 description 的值,因此处理器在处理它对应的注解时,通过 description() 取得的是默认值 “no description”。

    默认值限制--一般不会使用null

    // annotations/SimulatingNull.java
    import java.lang.annotation.*;
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface SimulatingNull {
        int id() default -1;
        String description() default "";
    }

    注解还有个常用地方就是单元测试

    API 的提供方和框架将会将注解作为他们工具的一部分。通过 @Unit 系统,我们可以想象,注解会极大的改变我们的 Java 编程体验。

    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    vb教程图文并茂
    一个文本框的andriod教程
    5月18日,完成导入数据,但是从命令行显示数据乱码,程序已经正常工作
    android 文件读写权限的设定
    raw目录的位置是D:android_projectsqrscanappsrcmain es aw
    一个在raw里面放着数据库文件的网上例子
    P1446 [HNOI2008]Cards [Burnside引理]
    UVA11255 Necklace [Polya定理]
    Polya 定理入门[Burnside引理,Polya定理,欧拉函数]
    P2831 愤怒的小鸟 [状压dp/模拟退火]
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12017440.html
Copyright © 2011-2022 走看看