zoukankan      html  css  js  c++  java
  • Java 基础 —— 注解

    注解(annotation)不是注释(comment);

    注解,是一种元数据(metadata),可为我们在代码中添加信息提供了一种形式化的方法。注解在一定程度上实现了元数据和源代码文件的结合,而不是将元数据保存在外部文档中。

    Java SE5 在 java.lang 中定义的三种基本注释:

    • @Override
    • @Deprecated
    • @SuppressWarnings

    以及 4 中元注解:

    • @Target
    • @Retention
      • RetentionPolicy.SOURCE – 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
      • RetentionPolicy.CLASS – 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
      • RetentionPolicy.RUNTIME– 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
    • @Documented(将此注解包含在 doc 中)
    • @Inherited(允许子类继承父类中的注解)

    1. 定义注解

    可以看到,注解的定义看起来很像接口(@interface)的定义。事实上,与其他任何 java 接口一样,注解也会被编译成 .class 文件:

    @Target(ElementType.METHOD)     // java.lang.annotation.ElementType/Target
    @Retention(RetentionPolicy.RUNTIME) // java.lang.annotation.Retention/RententionPolicy;
    public @interface Test {}

    定义注解时,会需要一些元注解(meta-annotation),比如上例的 @Target 和 @Retention。

    • @Target 用来定义你的注解将应用在什么地方
      • 一个方法(@Target(ElementType.METHOD)),
      • 或是一个域(成员变量,@Target(ELEMENTTYPE.FIELD))
      • ElementType.CONSTRUCTOR
      • ElementType.LOCAL_VARIABLE
      • ElementType.PACKAGE
      • ElementType.TYPE
      • ElementType.PARAMETER
    • @Retention 用来定义该注解在哪一级别可用:
      • SOURCE:源代码中;
      • CLASS:类文件中;
      • RUNTIME:运行时;

    在注解上,一般也会包含一些元素以表示某些值。当搜集分析处理注解时,程序或者工具可以利用这些值(没有元素的注解称为标记注解 marker annotation,也即仅起到标记作用,如上例的 @Test)。注解的元素看起来就像接口的方法,唯一的区别你可以为其指定默认值。

    2. 注解的应用

    如下为一个用来跟踪项目用例的注解。如果一个方法或一组方法实现了某个用例的需求,那么程序员可以为此方法加上注解。项目经理便可通过计算已经实现的用例,以掌握项目的进展。

    // UseCase.java
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface UseCase {
        public int id();
        public String description() default "no description";
    }
    
    // PasswordUtils
    public class PasswordUtils {
        @UseCase(id = 47, description = "password must contains at least one numeric")
        public boolean validatePassword(String password) {
            return password.matches("\w*\d\w*");
        }
    
        @UseCase(id = 48)
        public String entryptPassword(String password) {
            return new StringBuilder(password).reverse().toString();
        }
    
        @UseCase(id = 49, description = "new password can't equal previously used ones")
        public boolean checkForNewPassword(List<String> prevPasswords, String password) {
            return prevPasswords.contains(password);
        }
    }
  • 相关阅读:
    C#实现任意源组播与特定源组播
    张灵甫此人性格偏激,赌性重,喜欢冒险,做事不留后路,更适合担任中下层军官(要自己掌控着自己的命运)
    Delphi 中 断言 Assert 用法
    桌面程序阻止Windows关机(使用Message.Result取得DefWindowProc API函数的返回值,非常重要)
    Asp.net vnext的IIS部署
    Asp.net vNext 学习3
    EasyUI的后台界面
    C#框架
    前端分离规范
    AngularJS html5Mode与ASP.NET MVC路由
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9421206.html
Copyright © 2011-2022 走看看