Saul's blog Saul's blog
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)

Saul.J.Wu

立身之本,不在高低。
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)
  • Java入门基础

  • Java核心基础

    • 多线程

    • Java常用类

    • 枚举类与注解

      • 枚举类
      • 注解
        • 学习目标
        • 注解(Annotation)概述
        • 常见的Annotation示例
          • 示例一
          • 示例二
          • 示例三
          • 示例四
        • 自定义Annotation
        • JDK中的元注解
          • @Retention
          • @Target
          • @Documented
          • @Inherited
          • 小结
        • 利用反射获取注解信息(在反射部分涉及)
        • JDK 8中注解的新特性
          • @Repeatable
          • 类型的注解
    • Java集合

    • 数据结构与算法

    • 泛型

    • IO流

    • 网络编程

    • 反射

    • 函数式编程

  • 设计模式

  • Web开发

  • SpringBoot

  • 微服务

  • Elasticsearch

  • 运维

  • 后端
  • Java核心基础
  • 枚举类与注解
SaulJWu
2020-12-24

注解

# 学习目标

  • 注解(Annotation)概述
  • 常见的Annotation示例
  • 自定义Annotation
  • JDK中的元注解
  • 利用反射获取注解信息(在反射部分涉及)
  • JDK 8中注解的新特性

# 注解(Annotation)概述

  • 从JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是Annotation(注解)
  • Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理。
    • 通过使用Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。
    • 代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
  • Annotation 可以像修饰符一样被使用, 可用于修饰包,类, 构造器, 方法, 成员变量, 参数, 局部变量的声明, 这些信息被保存在Annotation 的name=value 对中。
  • 在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE/Android中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗代码和XML配置等。
  • 未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是基于注解的了,注解是一种趋势,一定程度上可以说:框架= 注解+ 反射+ 设计模式。

# 常见的Annotation示例

  • 使用Annotation 时要在其前面增加@ 符号, 并把该Annotation 当成一个修饰符使用。用于修饰它支持的程序元素

# 示例一

示例一:生成文档相关的注解

  • @author标明开发该类模块的作者,多个作者之间使用,分割
  • @version标明该类模块的版本
  • @see参考转向,也就是相关主题
  • @since从哪个版本开始增加的
  • @param对方法中某参数的说明,如果没有参数就不能写
  • @return对方法返回值的说明,如果方法的返回值类型是void就不能写
  • @exception对方法可能抛出的异常进行说明,如果方法没有用throws显式抛出的异常就不能写

注意:

  • @param@return和@exception这三个标记都是只用于方法的。
  • @param的格式要求:@param形参名形参类型形参说明
  • @return的格式要求:@return返回值类型返回值说明
  • @exception的格式要求:@exception异常类型异常说明
  • @param和@exception可以并列多个

# 示例二

示例二:在编译时进行格式检查(JDK内置的三个基本注解)

  • @Override: 限定重写父类方法, 该注解只能用于方法
  • @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
  • @SuppressWarnings: 抑制编译器警告

# 示例三

跟踪代码依赖性,实现替代配置文件功能

Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署。

image-20201224010548260

# 示例四

spring框架中关于“事务”的管理

image-20201224010621852

# 自定义Annotation

  • 1、定义新的Annotation类型使用@interface关键字

    • 自定义注解自动继承了java.lang.annotation.Annotation接口

    2、Annotation的成员变量在Annotation定义中以无参数方法的形式来声明。其方法名和返回值定义了该成员的名字和类型。我们称为配置参数。

    • 类型只能是八种基本数据类型、String类型、Class类型、enum类型、Annotation类型、以上所有类型的数组。
  • 3、可以在定义Annotation的成员变量时为其指定初始值,指定成员变量的初始值可使用default关键字

    • 如果只有一个参数成员,建议使用参数名为value
    • 如果定义的注解含有配置参数,那么使用时必须指定参数值,除非它有默认值。格式是参数名=参数值,如果只有一个参数成员,且名称为value,可以省略value=
  • 4、没有成员定义的Annotation称为标记;包含成员变量的Annotation称为元数据Annotation

**注意:**自定义注解必须配上注解的信息处理流程才有意义。

实例

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnoation {
    String value() default "hello";
}

1
2
3
4
5
6
7
8
9
10
11
@MyAnnoation(value = "test")
public class Demo {
    public static void main(String[] args) {
        Class clazz = Demo.class;
        Annotation a = clazz.getAnnotation(MyAnnoation.class);
        MyAnnoation m = (MyAnnoation)a;
        String info = m.value();
        System.out.println("info = " + info);
    }
}
1
2
3
4
5
6
7
8
9
10

输出结果:

info = test
1

# JDK中的元注解

  • JDK 的元Annotation 用于修饰其他Annotation 定义
  • JDK5.0提供了4个标准的meta-annotation类型,分别是:
    • Retention
    • Target
    • Documented
    • Inherited

# @Retention

只能用于修饰一个Annotation 定义, 用于指定该Annotation 的生命周期, @Rentention包含一个RetentionPolicy类型的成员变量, 使用@Rentention时必须为该value 成员变量指定值:

  • RetentionPolicy.SOURCE:在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释
  • RetentionPolicy.CLASS:在class文件中有效(即class保留),当运行Java 程序时, JVM 不会保留注解。这是默认值。
  • RetentionPolicy.RUNTIME:在运行时有效(即运行时保留),当运行Java 程序时, JVM 会保留注释。程序可以通过反射获取该注释。

# @Target

用于修饰Annotation 定义, 用于指定被修饰的Annotation 能用于修饰哪些程序元素。@Target 也包含一个名为value的成员变量

image-20201224013218064

image-20201224013350437

# @Documented

用于指定被该元Annotation 修饰的Annotation 类将被javadoc工具提取成文档。默认情况下,javadoc是不包括注解的。

定义为Documented的注解必须设置Retention值为RUNTIME

# @Inherited

  • 被它修饰的Annotation 将具有继承性。
  • 如果某个类使用了被@Inherited 修饰的Annotation, 则其子类将自动具有该注解。
    • 比如:如果把标有@Inherited注解的自定义的注解标注在类级别上,子类则可以继承父类类级别的注解
    • 实际应用中,使用较少

# 小结

自定义注解注释通常都指明@Retention和@Target

# 利用反射获取注解信息(在反射部分涉及)

  • JDK 5.0 在java.lang.reflect包下新增了AnnotatedElement接口, 该接口代表程序中可以接受注解的程序元素
  • 当一个Annotation 类型被定义为运行时Annotation 后, 该注解才是运行时可见, 当class 文件被载入时保存在class 文件中的Annotation 才会被虚拟机读取
  • 程序可以调用AnnotatedElement对象的如下方法来访问Annotation 信息

image-20201224013938152

# JDK 8中注解的新特性

Java 8对注解处理提供了两点改进:可重复的注解及可用于类型的注解。此外,反射也得到了加强,在Java8中能够得到方法参数的名称。这会简化标注在方法参数上的注解。

# @Repeatable

  • 在类名上声明,成员值为类名.class
  • 新类名的@Target和@retention、@Inherited等元注解都要与以前保持一致

可重复的注解@Repeatable示例:

image-20201224014112554

# 类型的注解

JDK1.8之后,关于元注解@Target的参数类型ElementType枚举值多了两个:

  • TYPE_PARAMETER
  • TYPE_USE

在Java8之前,注解只能是在声明的地方所使用,Java8开始,注解可以应用在任何地方。

说明:

  • ElementType.TYPE_PARAMETER表示该注解能写在类型变量的声明语句中(如:泛型声明)。

  • ElementType.TYPE_USE表示该注解能写在使用类型的任何语句中。

ElementType.TYPE_PARAMETER示例

image-20201224014847787

ElementType.TYPE_USE示例

image-20201224014928702

帮我改善此页面 (opens new window)
#注解#Annotation#元数据#MetaData
上次更新: 2020/12/24, 05:51:23
枚举类
Java集合框架概述

← 枚举类 Java集合框架概述→

最近更新
01
zabbix学习笔记二
02-28
02
zabbix学习笔记一
02-10
03
Linux访问不了github
12-08
更多文章>
Theme by Vdoing | Copyright © 2020-2022 Saul.J.Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式