博客
关于我
Java注解的使用
阅读量:212 次
发布时间:2019-02-28

本文共 4128 字,大约阅读时间需要 13 分钟。

Java注解(Annotation)概述

从JDK 5.0开始,Java引入了对元数据的支持,即注解(Annotation)。注解是一种特殊的标记,可以在编译、类加载和运行时被读取并执行相应的处理。通过注解,开发者可以在不改变原有逻辑的情况下,在源文件中嵌入补充信息。代码分析工具、开发工具和部署工具可以利用这些信息进行验证或部署。

注解的使用场景

注解可以像修饰符一样使用,用于修饰包、类、构造器、方法、成员变量、参数、局部变量等。这些信息被保存在注解的“name=value”对中。

框架 = 注解 + 反射机制 + 设计模式

注解的示例

生成文档相关的注解

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

编译时格式检查

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

Servlet3.0中的注解

Servlet3.0引入了注解,使得不需要在web.xml文件中进行Servlet的部署。

Spring框架中的事务管理

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

自定义注解

定义新的注解类型

使用@interface关键字定义新的注解类型。自定义注解自动继承了java.lang.annotation.Annotation接口。

注解成员变量

注解成员变量通过无参数方法的形式声明,返回类型定义了成员的名字和类型。类型只能是八种基本数据类型、String类型、Class类型、enum类型、注解类型以上所有类型的数组。

初始化值

在定义注解成员变量时为其指定初始值,可以使用default关键字指定初始值。

标记和元数据注解

没有成员定义的注解称为标记注解;包含成员变量的注解称为元数据注解。

使用注解时的注意事项

如果注解有成员,使用注解时需要指明成员的值。

JDK中的元注解

元注解是对现有注解进行解释说明的注解。

@Retention

用于指定注解的生命周期,包含一个RetentionPolicy类型的成员变量,必须为value成员变量指定值:

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

@Target

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

@Documented

用于指定被该元注解修饰的注解类将被Javadoc工具提取成文档。默认情况下,Javadoc不包括注解。定义为Documented的注解必须设置Retention值为RUNTIME。

@Inherited

被它修饰的注解将具有继承性。如果某个类使用了被@Inherited修饰的注解,其子类将自动具有该注解。

利用反射获取注解信息

在java.lang.reflect包下新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素。当一个Annotation类型被定义为运行时Annotation后,该注解才是运行时可见的,当class文件被载入时保存在class文件中的Annotation才会被虚拟机读取。

程序可以调用AnnotatedElement对象的如下方法来访问Annotation信息:

  • getAnnotations():返回注解数组。
  • getAnnotation(Class
    annotationClass):返回指定类型的注解。

示例:

@Testpublic void testGetAnnotation() {    Class clazz = Person.class;    Annotation[] annotations = clazz.getAnnotations();    for (int i = 0; i < annotations.length; i++) {        System.out.println(annotations[i]);    }}

输出结果:

@MyAnnotation(value="hello")

JDK8中的注解新特性

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

可重复的注解

定义一个MyAnnotations注解,里面是MyAnnotation的一个数组:

public @interface MyAnnotations {    MyAnnotation[] value();}

通过@MyAnnotations来重复使用@MyAnnotation:

@MyAnnotations({@MyAnnotation(value="hello"), @MyAnnotation(value="world")}) class Person {    private String name;    private int age;    public Person() {}    public Person(String name, int age) {        this.name = name;        this.age = age;    }    public void walk() {        System.out.println("人走路");    }    public void eat() {        System.out.println("人吃饭");    }}

在JDK8之后可以使用@Repeatable这个注解:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotations {    MyAnnotation[] value();}

在MyAnnotation上声明@Repeatable,成员值为MyAnnotations.class:

@Repeatable(MyAnnotations.class)@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation {    String value() default "hello";}

这样@MyAnnotation这个注解就可以重复使用了:

@MyAnnotation(value="hello")@MyAnnotation(value="world") class Person {    private String name;    private int age;    public Person() {}    public Person(String name, int age) {        this.name = name;        this.age = age;    }    public void walk() {        System.out.println("人走路");    }    public void eat() {        System.out.println("人吃饭");    }}

可用于类型的注解

@Repeatable(MyAnnotations.class)@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER})public @interface MyAnnotation {String value() default "hello";}

示例:

class Generic
{ }

@Repeatable(MyAnnotations.class)@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, TYPE_PARAMETER, TYPE_USE})public @interface MyAnnotation {String value() default "hello";}

示例:

class Generic
{ public void show() throws @MyAnnotation RuntimeException { ArrayList
arrayList = new ArrayList<>(); int num = (@MyAnnotation int) 10L; }}

转载地址:http://dnpi.baihongyu.com/

你可能感兴趣的文章
Nginx运维与实战(二)-Https配置
查看>>
Nginx配置Https证书
查看>>
Nginx配置ssl实现https
查看>>
Nginx配置TCP代理指南
查看>>
Nginx配置——不记录指定文件类型日志
查看>>
nginx配置一、二级域名、多域名对应(api接口、前端网站、后台管理网站)
查看>>
Nginx配置代理解决本地html进行ajax请求接口跨域问题
查看>>
nginx配置全解
查看>>
Nginx配置参数中文说明
查看>>
nginx配置域名和ip同时访问、开放多端口
查看>>
Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
查看>>
Nginx配置如何一键生成
查看>>
Nginx配置实例-负载均衡实例:平均访问多台服务器
查看>>
Nginx配置文件nginx.conf中文详解(总结)
查看>>
Nginx配置负载均衡到后台网关集群
查看>>
ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
查看>>
NHibernate学习[1]
查看>>
NHibernate异常:No persister for的解决办法
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
查看>>
NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
查看>>