博客
关于我
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/

你可能感兴趣的文章
Netty源码—8.编解码原理一
查看>>
Netty源码—8.编解码原理二
查看>>
Netty源码解读
查看>>
Netty的Socket编程详解-搭建服务端与客户端并进行数据传输
查看>>
Netty相关
查看>>
Netty遇到TCP发送缓冲区满了 写半包操作该如何处理
查看>>
Netty:ChannelPipeline和ChannelHandler为什么会鬼混在一起?
查看>>
Netty:原理架构解析
查看>>
Network Dissection:Quantifying Interpretability of Deep Visual Representations(深层视觉表征的量化解释)
查看>>
Network Sniffer and Connection Analyzer
查看>>
Network 灰鸽宝典【目录】
查看>>
NetworkX系列教程(11)-graph和其他数据格式转换
查看>>
Networkx读取军械调查-ITN综合传输网络?/读取GML文件
查看>>
network小学习
查看>>
Netwox网络工具使用详解
查看>>
Net与Flex入门
查看>>
net包之IPConn
查看>>
Net操作配置文件(Web.config|App.config)通用类
查看>>
Neutron系列 : Neutron OVS OpenFlow 流表 和 L2 Population(7)
查看>>
New Relic——手机应用app开发达人的福利立即就到啦!
查看>>