Java Annotation Tutorials

注:本文主要翻译自Lesson: Annotations,学习一下Java注解。

Annotations(注解)是一种元数据(metadata),用于描述一段程序但对程序的运行不产生直接影响。

注解有一些作用,其中包括:

  • 为编译器提供信息——注解可以被编译器用于探测 errors 或者 suppress warnings。
  • 编译时或部署时处理——软件处理注解后可生成代码,XML 文件等。
  • 运行时处理——一些注解可以用于运行时检查。

Annotations基础

注解的格式

注解最简单的格式如下:

@Entity

@字符告知编译器接下来是一个注解,下面这个例子是一个名为Override的注解:

@Override
void mySuperMethod() { ... }

注解还可以包含一些带命名或不带命名的元素,每个元素会有相应的 value:

@Author(
   name = "Benjamin Franklin",
   date = "3/27/2003"
)
class MyClass() { ... }

@SuppressWarnings(value = "unchecked")
void myMethod() { ... }

如果只包含一个带命名的 value,那么这个 value 的 name 可以忽略:

@SuppressWarnings("unchecked")
void myMethod() { ... }

如果注解里没有元素,那么括号可以被省略,参考前面的@Override示例。

对于同一个声明,可以用多个注解:

@Author(name = "Jane Doe")
@EBook
class MyClass { ... }

如果注解的类型相同,这种情况被称为重复注解(repeating annotation):

@Author(name = "Jane Doe")
@Author(name = "John Smith")
class MyClass { ... }

重复注解自 Java 8 开始支持,详见 Repeating Annotations 部分。

注解的类型可以是java.langjava.lang.annotation包下面定义的类型,比如前面例子中的OverrideSuppressWarnings就是 Java 预置的注解类型。此外还可以自定义注解类型,如前面例子中的AuthorEbook

注解可以用在什么地方

注解可以用于声明类、域、方法和其他程序的元素,当用于声明时,注解往往自成一行。

从 Java 8 开始,注解还可作为类型(type),如下:

  • 创建类的实例:

    new @Interned MyObject();
  • 转型:

    myString = (@NonNull String) str;
  • 实现接口:
    java class UnmodifiableList<T> implements @Readonly List<@Readonly T> { ... }

  • 抛异常的声明:
    java void monitorTemperature() throws @Critical TemperatureException { ... }

这种形式的注解被称为类型注解(type annotation)。

声明一个注解类型

在代码中很多注解代替了注释(comments)。

比如,一个开发团队通常在一个类的 body 起始的位置添加一些重要的注释:

public class Generation3List extends Generation2List {

   // Author: John Doe
   // Date: 3/17/2002
   // Current revision: 6
   // Last modified: 4/12/2004
   // By: Jane Doe
   // Reviewers: Alice, Bill, Cindy

   // class code goes here

}

如果使用注解的话,首先要定义一个注解类型,语法如下:

@interface ClassPreamble {
   String author();
   String date();
   int currentRevision() default 1;
   String lastModified() default "N/A";
   String lastModifiedBy() default "N/A";
   // Note use of array
   String[] reviewers();
}

注解的定义和接口的定义有些像,interface前面多了个@

上面这个注解的定义中包括了注解类型和元素声明,其中 default 值是可选的。

定义好注解之后,我们可以像下面这样使用它:

@ClassPreamble (
   author = "John Doe",
   date = "3/17/2002",
   currentRevision = 6,
   lastModified = "4/12/2004",
   lastModifiedBy = "Jane Doe",
   // Note array notation
   reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List {

// class code goes here

}

Note:为了让 Java Doc 包含注解@ClassPreamble的信息,我们需要在定义@ClassPreamble时为它再加上注解@Documented

```java
// import this to use @Documented
import java.lang.annotation.*;

@Documented
@interface ClassPreamble {

// Annotation element definitions

}
```

预置的注解类型

Java API 中预定义了一些注解类型,一些用于编译器,还有一些用于其它注解。

Java使用的注解类型

java.lang中预置的注解有:@Deprecated, @Override, 和 @SuppressWarnings

@Deprecated注解表示被标记的元素是deprecated的,不建议再使用的元素。当程序使用了被@Deprecated注解的方法、类或域时,编译器会生成一个warning信息。当一个元素是deprecated,在Javadoc中也要使用@deprecated标记,Doc中的d小写,注解中是大写的D

 // Javadoc comment follows
    /**
     * @deprecated
     * explanation of why it was deprecated
     */
    @Deprecated
    static void deprecatedMethod() { }
}

@Override注解告诉编译器,该方法是重写自父类的方法:

// mark method as a superclass method
   // that has been overridden
   @Override 
   int overriddenMethod() { }

@Override的好处是如果这个方法没用正确重写父类的方法时,编译器会产生一个 error 提示。

@SuppressWarnings注解提示编译器不用产生指定的 warning 信息,如调用一个 deprecated 方法时,编译器会生成一个 waring 提示,使用@SuppressWarnings注解后,这个 waring 就被抑制了:

// use a deprecated method and tell 
   // compiler not to generate a warning
   @SuppressWarnings("deprecation")
    void useDeprecatedMethod() {
        // deprecation warning
        // - suppressed
        objectOne.deprecatedMethod();
    }

@SafeVarargs用于方法或构造器时,断言可变参数不会产生潜在的危险,由可变参数使用而产生的 warning 会被 suppressed。

@FunctionalInterface是Java 8引入的,表示函数式接口。

注解的注解

用于其它注解的注解,被称为元注解(meta-annotations),下面设计java.lang.annotation包里的相关注解。

@Retention指定了注解的保留方式:

  • RetentionPolicy.SOURCE – 被标记的注解只保留在源码级别,会被编译器忽略。
  • RetentionPolicy.CLASS – 被标记的注解保留至编译时,会被JVM忽略。
  • RetentionPolicy.RUNTIME – 被标记的注解被JVM保留,会用于运行时环境。

@Documented注解信息会被 Javadoc 工具写入文档。

@Target起限制作用,表示注解用于描述哪种 Java 元素:

  • ElementType.ANNOTATION_TYPE 用于描述注解
  • ElementType.CONSTRUCTOR 用于描述构造器
  • ElementType.FIELD 用于描述域
  • ElementType.LOCAL_VARIABLE 用于描述局部变量
  • ElementType.METHOD 用于描述方法的注解
  • ElementType.PACKAGE 用于描述包
  • ElementType.PARAMETER 用于描述参数
  • ElementType.TYPE 用于描述一个类的任何元素

@Inherited表示该注解是可以被继承的,只能用于声明类。

@Repeatable在Java 8引入,表示被标记的注解可以被重复用于同一个声明。


扩展阅读:

转载于:https://www.cnblogs.com/kodyan/p/5442648.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值