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

你可能感兴趣的文章
python 加密解密(base64, AES)
查看>>
Python 包管理器和 Node.js
查看>>
Python 单词字母顺序不变且所有倒排
查看>>
python 反射机制
查看>>
python 启动提示IDLE's subprocess didn't make conne...
查看>>
python 命令接口_实现“[命令][操作][参数]”样式的命令行接口?
查看>>
Python 和 OpenCV.如何检测图像中的所有(填充)圆形/圆形对象?
查看>>
Python 和 RabbitMQ - 聆听来自多个渠道的消费事件的最佳方式?
查看>>
python编辑器打不开_关于命令ride.py打不开RF,而是打开pycharm编辑器问题解决思路...
查看>>
python编译exe同时支持32位_第三周:同时管理64位和32位版本的Python,并用Pyinstaller打包成exe...
查看>>
Python 和Java 哪个更适合做自动化测试?
查看>>
Python编程:掌握高级语言程序设计。从零基础到精通,收藏这篇就够了!
查看>>
python 图片转ico
查看>>
python 图片转文字、语音转文字、文字转语音保存音频并朗读
查看>>
python 在包含类似字符\x16、\x12、\x某某的数组中将以\x开头的字符找出来的方法
查看>>
Python 在并行进程之间共享字典
查看>>
Python 垃圾收集器文档
查看>>
python 基于 wordcloud + jieba + matplotlib 生成词云
查看>>
python 基于detectron或mask_rcnn的mask遮罩区域进行图片截取
查看>>
Python编程:Tkinter图形界面设计(2)
查看>>