java运行时读取注解_Java自定义注解和运行时靠反射获取注解

转:1、Annotation的工作原理:

JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型。该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的class文件和一个注解处理工具组成。

Annotation并不直接影响代码的语义,但是他可以被看做是程序的工具或者类库。它会反过来对正在运行的程序语义有所影响。

Annotation可以冲源文件、class文件或者在运行时通过反射机制多种方式被读取。2、@Override注解:

java.lang

注释类型 Override

@Target(value=METHOD)

@Retention(value=SOURCE)public @interfaceOverride

表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。

@Override注解表示子类要重写父类的对应方法。

Override是一个Marker annotation,用于标识的Annotation,Annotation名称本身表示了要给工具程序的信息。

下面是一个使用@Override注解的例子:classA {privateString id;

A(String id){this.id =id;

}

@OverridepublicString toString() {returnid;

}

}3、@Deprecated注解:

java.lang

注释类型 Deprecated

@Documented

@Retention(value=RUNTIME)public @interfaceDeprecated

用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。

@Deprecated注解表示方法是不被建议使用的。

Deprecated是一个Marker annotation。

下面是一个使用@Deprecated注解的例子:classA {privateString id;

A(String id){this.id =id;

}

@Deprecatedpublic voidexecute(){

System.out.println(id);

}public static voidmain(String[] args) {

A a= new A("a123");

a.execute();

}

}4、@SuppressWarnings注解:

java.lang

注释类型 SuppressWarnings

@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})

@Retention(value=SOURCE)public @interfaceSuppressWarnings

指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。

根据风格不同,程序员应该始终在最里层的嵌套元素上使用此注释,在那里使用才有效。如果要在特定的方法中取消显示某个警告,则应该注释该方法而不是注释它的类。

@SuppressWarnings注解表示抑制警告。

下面是一个使用@SuppressWarnings注解的例子:

@SuppressWarnings("unchecked")public static voidmain(String[] args) {

List list= newArrayList();

list.add("abc");

}5、自定义注解:

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。

自定义最简单的注解:public @interfaceMyAnnotation {

}

使用自定义注解:public classAnnotationTest2 {

@MyAnnotationpublic voidexecute(){

System.out.println("method");

}

}5.1、添加变量:public @interfaceMyAnnotation {

String value1();

}

使用自定义注解:public classAnnotationTest2 {

@MyAnnotation(value1="abc")public voidexecute(){

System.out.println("method");

}

}

当注解中使用的属性名为value时,对其赋值时可以不指定属性的名称而直接写上属性值接口;除了value意外的变量名都需要使用name=value的方式赋值。5.2、添加默认值:public @interfaceMyAnnotation {

String value1()default "abc";

}5.3、多变量使用枚举:public @interfaceMyAnnotation {

String value1()default "abc";

MyEnum value2()defaultMyEnum.Sunny;

}enumMyEnum{

Sunny,Rainy

}

使用自定义注解:public classAnnotationTest2 {

@MyAnnotation(value1="a", value2=MyEnum.Sunny)public voidexecute(){

System.out.println("method");

}

}5.4、数组变量:public @interfaceMyAnnotation {

String[] value1()default "abc";

}

使用自定义注解:public classAnnotationTest2 {

@MyAnnotation(value1={"a","b"})public voidexecute(){

System.out.println("method");

}

}6、设置注解的作用范围:

@Documented

@Retention(value=RUNTIME)

@Target(value=ANNOTATION_TYPE)public @interfaceRetention

指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。

只有元注释类型直接用于注释时,Target 元注释才有效。如果元注释类型用作另一种注释类型的成员,则无效。public enumRetentionPolicyextends Enum注释保留策略。此枚举类型的常量描述保留注释的不同策略。它们与 Retention 元注释类型一起使用,以指定保留多长的注释。

CLASS

编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。

RUNTIME

编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。

SOURCE

编译器要丢弃的注释。

@Retention注解可以在定义注解时为编译程序提供注解的保留策略。

属于CLASS保留策略的注解有@SuppressWarnings,该注解信息不会存储于.class文件。6.1、在自定义注解中的使用例子:

@Retention(RetentionPolicy.CLASS)public @interfaceMyAnnotation {

String[] value1()default "abc";

}7、使用反射读取RUNTIME保留策略的Annotation信息的例子:

java.lang.reflect

接口 AnnotatedElement

所有已知实现类:

AccessibleObject, Class, Constructor, Field, Method, Package

表示目前正在此 VM 中运行的程序的一个已注释元素。该接口允许反射性地读取注释。由此接口中的方法返回的所有注释都是不可变并且可序列化的。调用者可以修改已赋值数组枚举成员的访问器返回的数组;这不会对其他调用者返回的数组产生任何影响。

如果此接口中的方法返回的注释(直接或间接地)包含一个已赋值的 Class 成员,该成员引用了一个在此 VM 中不可访问的类,则试图通过在返回的注释上调用相关的类返回的方法来读取该类,将导致一个 TypeNotPresentException。

isAnnotationPresentboolean isAnnotationPresent(Class extends Annotation>annotationClass)

如果指定类型的注释存在于此元素上,则返回true,否则返回 false。此方法主要是为了便于访问标记注释而设计的。

参数:

annotationClass-对应于注释类型的 Class 对象

返回:

如果指定注释类型的注释存在于此对象上,则返回true,否则返回 false抛出:

NullPointerException- 如果给定的注释类为 null从以下版本开始:1.5getAnnotation T getAnnotation(ClassannotationClass)

如果存在该元素的指定类型的注释,则返回这些注释,否则返回null。

参数:

annotationClass-对应于注释类型的 Class 对象

返回:

如果该元素的指定注释类型的注释存在于此对象上,则返回这些注释,否则返回null抛出:

NullPointerException- 如果给定的注释类为 null从以下版本开始:1.5getAnnotations

Annotation[] getAnnotations()

返回此元素上存在的所有注释。(如果此元素没有注释,则返回长度为零的数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

返回:

此元素上存在的所有注释

从以下版本开始:1.5getDeclaredAnnotations

Annotation[] getDeclaredAnnotations()

返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

返回:

直接存在于此元素上的所有注释

从以下版本开始:1.5下面是使用反射读取RUNTIME保留策略的Annotation信息的例子:

自定义注解:

@Retention(RetentionPolicy.RUNTIME)public @interfaceMyAnnotation {

String[] value1()default "abc";

}

使用自定义注解:public classAnnotationTest2 {

@MyAnnotation(value1={"a","b"})

@Deprecatedpublic voidexecute(){

System.out.println("method");

}

}

读取注解中的信息:public static void main(String[] args) throwsSecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {

AnnotationTest2 annotationTest2= newAnnotationTest2();

Class c = AnnotationTest2.class;

Method method= c.getMethod("execute", newClass[]{});if(method.isAnnotationPresent(MyAnnotation.class)){

MyAnnotation myAnnotation= method.getAnnotation(MyAnnotation.class);

method.invoke(annotationTest2,newObject[]{});

String[] value1=myAnnotation.value1();

System.out.println(value1[0]);

}

Annotation[] annotations=method.getAnnotations();for(Annotation annotation : annotations){

System.out.println(annotation);

}

}8、限定注解的使用:

限定注解使用@Target。

@Documented

@Retention(value=RUNTIME)

@Target(value=ANNOTATION_TYPE)public @interfaceTarget

指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。 例如,此元注释指示该声明类型是其自身,即元注释类型。它只能用在注释类型声明上:

@Target(ElementType.ANNOTATION_TYPE)public @interfaceMetaAnnotationType {

...

}

此元注释指示该声明类型只可作为复杂注释类型声明中的成员类型使用。它不能直接用于注释:

@Target({})public @interfaceMemberType {

...

}

这是一个编译时错误,它表明一个 ElementType 常量在 Target 注释中出现了不只一次。例如,以下元注释是非法的:

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})public @interfaceBogus {

...

}public enumElementTypeextends Enum程序元素类型。此枚举类型的常量提供了 Java 程序中声明的元素的简单分类。

这些常量与 Target 元注释类型一起使用,以指定在什么情况下使用注释类型是合法的。

ANNOTATION_TYPE

注释类型声明

CONSTRUCTOR

构造方法声明

FIELD

字段声明(包括枚举常量)

LOCAL_VARIABLE

局部变量声明

METHOD

方法声明

PACKAGE

包声明

PARAMETER

参数声明

TYPE

类、接口(包括注释类型)或枚举声明

注解的使用限定的例子:

@Target(ElementType.METHOD)public @interfaceMyAnnotation {

String[] value1()default "abc";

}9、在帮助文档中加入注解:

要想在制作JavaDoc文件的同时将注解信息加入到API文件中,可以使用java.lang.annotation.Documented。

在自定义注解中声明构建注解文档:

@Documentedpublic @interfaceMyAnnotation {

String[] value1()default "abc";

}

使用自定义注解:public classAnnotationTest2 {

@MyAnnotation(value1={"a","b"})public voidexecute(){

System.out.println("method");

}

}10、在注解中使用继承:

默认情况下注解并不会被继承到子类中,可以在自定义注解时加上java.lang.annotation.Inherited注解声明使用继承。

@Documented

@Retention(value=RUNTIME)

@Target(value=ANNOTATION_TYPE)public @interfaceInherited

指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。

注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/427762.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python递归函数

递归函数简单来说就是函数的自我调用。使用递归函数很多时候可以使得代码简洁,优雅。可以把复杂的问题分解成简单的子问题。递归有无与伦比的魅力,从著名的计算机名言就可以看出递归的奇妙: To iterate is human,to recurse divine. 迭代者为…

java的jsp要下载吗_jsp、java下载附件

1 传入此jsp中的参数均已URLDencoder过。23 4 5 6 7 boolean isError false;8 String errorMsg "";9 response.reset();//可以加也可以不加10 request.setCharacterEncoding("UTF-8");11 String folder "news";12 if(request.getParameter(&q…

浅谈高斯消元的实现和简单应用

一、高斯消元的原理 对于n元的m个线性方程组成的方程组,我们将其以矩阵的形式记录下来: a11 a12 a13 ...... a1n b1 a21 a22 a23 ...... a2n b2 ... ... ... an1 an2 an3 ...... ann bn 然后进行初等行列变换,尝试构造出一个上三角矩阵&#…

java知识体系 servlet_03-Servlet 体系结构知识梳理

一、Servlet体系结构Java Web应用是基于Servlet规范运行,Servlet顶层类的关联如下图:从图可看出,Servlet规范基本围绕这几个类运行,其中,与Servlet主动关联的有3个类,分别是ServletRequest、ServletRespons…

SQL批量提交修改业务

把你需要批量提交修改的东西在内存中修改完毕 然后执行以下代码 SqlConnection conn new SqlConnection(ConnectionString);SqlDataAdapter sda new SqlDataAdapter("select Id,RankSummary,RankOfCn,Classify from u_College;", conn); //这里的SQL语句可以是查询…

testlink自带java api_java如何连接testlink

1.下载相关的jar包2.获取到testlink的url和key,注意:url不是testlink的连接地址,是连接地址/lib/api/xmlrpc.php3.测试是否连接成功public static void main(String args[]) {String url "http://test.tl.gmsd.lan/lib/api/xmlrpc.php&…

ubuntu解压缩zip/tar/tar.gz/tar.bz2

ubuntu解压缩zip/tar/tar.gz/tar.bz2ZIPzip可能是目前使用得最多的文档压缩格式。它最大的优点就是在不同的操作系统平台,比如Linux, Windows以及Mac OS,上使用。缺点就是支持的压缩率不是很高,而tar.gz和tar.gz2在压缩率方面做得…

lr背景虚化_lr背景虚化_怎样拍出背景模糊的照片

除了锐化之外,要获得独特的,令人难忘的图像,还可以使用其他方法,例如,相反的效果-单个细节的模糊。这样的方法将使人们有可能专注于整个构图的中心人物,为图片增加情感色彩,动作,并为…

MySql Delimiter

Delimiter 重新定义结束符,delimiter 默认情况下是 分号 (;) ,即默认情况下,Mysql解释器,遇到分号,则执行该命令。 但在mysql可视化图形客户端编辑命令时,当编辑的sql语句存在多行命…

在线五子棋JAVA网络编程_实验五 Java网络编程及安全

一、实验内容1.掌握Socket程序的编写;2.掌握密码技术的使用;3.设计安全传输系统。二、实验步骤1. 基于Java Socket实现安全传输2. 基于TCP实现客户端和服务器,结对编程一人负责客户端,一人负责服…

Python学习之==文件操作

1、打开文件的模式 1 r,只读模式(默认)【不可写;文件不存在,会报错】 2 w,只写模式【不可读;不存在则创建;存在则删除内容】 3 a,追加模式【不可读;不存在则创…

java多线程创建runnable_Java线程池和runnables创建runnables

有很多方法可以做你想要的 . 您需要小心,不要最终创建太多线程 .以下是一个示例,您可以使用ExecutorCompletionService提高效率,也可以使用Runnable .import java.util.ArrayList;import java.util.List;import java.util.Random;import java…

CF某gym G

题目大意&#xff1a;给定n个点&#xff0c;求一条直线最多能经过几个点(n<1000) 做法&#xff1a;大暴力。。。枚举每一个点作为直线的端点&#xff0c;然后求出剩下n-1个点和它的斜率&#xff0c;斜率相同的说明可以同时在一条直线上 #include<bits/stdc.h> #define…

java嵌入式开发neo4j_java-嵌入式Neo4j实际如何工作?

我是neo4j的新手,根据我到目前为止所做的阅读,似乎有两种方法可以使用Neo4j REST和Embedded与neo4j进行交互.我有点困惑的是,“嵌入式”选项是否仅使您能够使用本机Neo4j API操纵数据存储,还是可以嵌入Neo4j并将其与Java应用程序打包,如果可以的话,我该怎么做&#xff1f;解决方…

rnn中文语音识别java_语音识别算法阅读之RNN-T-2018

论文&#xff1a;EXPLORING ARCHITECTURES, DATA AND UNITS FOR STREAMING END-TO-END SPEECH RECOGNITION WITH RNN-TRANSDUCER,2018CTC的一个问题在于&#xff0c;其假设当前帧的输出与历史输出之间的条件独立性&#xff1b;RNN-T引入预测网络来弥补CTC这种条件独立性假设带来…

java数字不等于_java – 仅使用set中的数字查找等于或大于给定目标的总和

首先让我们将这个问题简化为整数而不是实数,否则我们将无法获得快速优化算法.例如,让我们将所有数字乘以100,然后将其四舍五入为下一个整数.所以说我们有项目大小x1,…,xn和目标大小Y.我们想要最小化该值k1 x1 … kn xn – Y在这种条件下(1) ki is a non-positive integer fo…

Mybatis 系列2-配置文件

【Mybatis 系列10-结合源码解析mybatis 执行流程】 【Mybatis 系列9-强大的动态sql 语句】 【Mybatis 系列8-结合源码解析select、resultMap的用法】 【Mybatis 系列7-结合源码解析核心CRUD配置及用法】 【Mybatis 系列6-结合源码解析节点配置objectFactory、databaseIdProvid…

python中restful接口开发实例_Python RESTful接口开发02

什么是RESTfulRESTful是一种设计思想&#xff0c;一种风格。RESTful主要包括 资源 和 对资源的操作。资源&#xff1a; 对实体的抽象&#xff0c;图书、音乐、电影、学生等都属于资源。对资源的操作&#xff1a; HTTP 方法 行为 示例 GET 获取资源的信息 http://example.com/…

Storm环境搭建(分布式集群)

作为流计算的开篇&#xff0c;笔者首先给出storm的安装和部署&#xff0c;storm的第二篇&#xff0c;笔者将详细的介绍storm的工作原理。下边直接上干货&#xff0c;跟笔者的步伐一块儿安装storm。 原文链接&#xff1a;Storm环境搭建&#xff08;分布式集群&#xff09; Step1…

php 红包算法,PHP语言:实现微信红包拆分算法

本文主要向大家介绍了PHP语言&#xff1a;实现微信红包拆分算法&#xff0c;通过具体的内容向大家展示&#xff0c;希望对大家学习php语言有所帮助。 修复最后一个红包输出未保留2位数 修复领取的红包金额低于最小红包限制* 红包分配算法** example* $coupon new Coupon(…