您的位置:首页 > 编程语言 > Java开发

Java 注解

2018-07-17 20:43 106 查看

注解(Annotation)在JDK1.5之后增加的一个新特性, 使用注解可以极大地简化编码提高开发效率,目前许多流行的框架(如Spring、MyBatis等)都大量使用注解。

编写注解类:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Author {

String name();

String email();

}

编写

Item
类测试注解:

@Author(name = "finley", email = "finley@example.com")
public class Item {

public static void main(String[] args) {
if (Item.class.isAnnotationPresent(Author.class)) {
Author author = Item.class.getAnnotation(Author.class);
System.out.println("author: " + author.name() + ", email: " + author.email());
}
}

}

上述示例在运行中获得了

Item
类被
@Author
注解的信息即注解中的参数。

工程开发中可以使用注解提供元信息,如Spring框架中

@Service
@Configuration
注解标注类的角色,
@Profile
@Import
注解标注类的元信息。

注解只是标记了元素的元信息,并不会直接影响代码的执行过程。

Class对象还提供了

getAnnotations()
等方法,可以参考JavaDoc。

元注解是标记注解类型的注解,上文在定义注解时使用的

@Target
@Retention
即为元注解。

@Target

@Target
标记注解元素类型, 由
ElementType
枚举定义:

  • TYPE
    : 修饰类(class)、接口(interface)和枚举(enum)
  • FIELD
    : 修饰域和枚举中定义的枚举常量
  • METHOD
    : 修饰方法
  • PARAMETER
    : 修饰方法的参数,如SpringMVC的
    @PathVariable
    注解
  • CONSTRUCTOR
    : 修饰构造器
  • LOCAL_VARIABLE
    : 修饰局部变量
  • ANNOTATION_TYPE
    : 修饰注解类,即元注解
  • PACKAGE
    : 修饰包

通常注解只能标记在声明处不能标记在使用处,如

Method
型注解只能标注在方法定义处不能标注在方法调用处。

在Java8之后Type注解可以标记在类型声明或使用处, Java8新增了两个

ElementType
:

  • TYPE_PARAMETER
    : 可以标记TYPE定义, 与1.8之前的
    TYPE
    相同
  • TYPE_USE
    : 可以标记TYPE使用,包括: 初始化对象时(new),对象类型转换, implements/extends声明,throws声明

可以使用

@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
指定两种Target。

@Retention

@Retention
标记注解被保留的时长, 由
RetentionPolicy
枚举定义:

  • SOURCE
    : 仅保留在源文件中
  • CLASS
    : 保留在源文件和编译生成的.class字节码文件中,但在运行时不再保留。 默认保留策略。
  • RUNTIME
    : 保留在源文件和编译生成的.class字节码文件以及运行时VM中,可以使用反射机制在运行时获得注解信息

@Inherited

@Inherited
表示注解可以被子类继承, 首先在基类上标记 Inherited 的注解:

@Author(name = "finley", email = "finley@example.com")
public class Base {
}

Item类没有使用

@Author
但它继承了基类的标记,因此我们可以获得
@Author
注解信息

public class Item extends Base {

public static void main(String[] args) {
if (Item.class.isAnnotationPresent(Author.class)) {
Author author = Item.class.getAnnotation(Author.class);
System.out.println("author: " + author.name() + ", email: " + author.email());
}
}

}

@Documented

@Documented
表示被标记的类型可以被JavaDoc工具文档化。

@Repeatable

在Java8之前同一个元素不能被相同的注解重复标记,

@Repeatable
允许一个注解重复标记同一个对象。

编写带有

@Repeatable
声明的注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(AuthorContainer.class)
public @interface Author {

String name();

String email();

}

编写Container注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthorContainer {
Author[] value();
}

AuthorContaier
必须提供声明方法
Author[] value();
,它的保留时间要长于
Author
且Target类型必须是
Author
目标类型的子集。

重复使用

@Author
标记:

@Author(name = "finley", email = "finley@example.com")
@Author(name = "finley2", email = "finley2@example.com")
public class Item extends Base {

public static void main(String[] args) {
if (Item.class.isAnnotationPresent(AuthorContainer.class)) {
AuthorContainer authorContainer = Item.class.getAnnotation(AuthorContainer.class);
for (Author author : authorContainer.value()) {
System.out.println("author: " + author.name() + ", email: " + author.email());
}
}
}

}

两次

@Author
标记被解释为
@AuthorContainer
标记,可以通过
authorContainer.value()
来访问每个
@Author
标记的信息。

注意

Item.class.isAnnotationPresent(Author.class)
会被判定为
false

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: