java定义注解

小伙伴们。今天我们来说说注解、标志@ 。针对java不同版本来说,注解的出现是在jdk1.5 但是在jdk1.5版本使用注解必须继续类的方法的重写,不能用于实现的接口中的方法实现,在jdk1.6环境下对于继续和实现都是用。

jdk1.5版本内置了三种标准的注解:

@Override,表示当前的方法定义将覆盖超类中的方法。

@Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。

@SuppressWarnings,关闭不当编辑器警告信息。

Java还提供了4中注解,专门负责新注解的创建:
@Target:

表示该注解可以用于什么地方,可能的ElementType参数有:
CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明

@Retention

表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
SOURCE:注解将被编译器丢弃
CLASS:注解在class文件中可用,但会被VM丢弃
RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息

@Document

将注解包含在Javadoc中

@Inherited

允许子类继承父类中的注解

下面我们自己来新建一个注解。在我们开发中。经常会使用自己设置的注解

首先我们创建一个注解类

package com.java.api;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/**定义注解* @Target:表示该注解可以用于什么地方,可能的ElementType参数有:
CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明
@Retention表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
SOURCE:注解将被编译器丢弃
CLASS:注解在class文件中可用,但会被VM丢弃
RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息* * */
public class UseCase{
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCases{public String id();public String description() default "no description";
}
}

然后我那使用注解

package com.java.api;import com.java.api.UseCase.UseCases;/*** 使用注解:* * */
public class PasswordUtils {@UseCases(id="47",description="Passwords must contain at least one numeric")public boolean validatePassword(String password) {return (password.matches("\\w*\\d\\w*"));}@UseCases(id ="48")public String encryptPassword(String password) {return new StringBuilder(password).reverse().toString();}
}

最后我们来测试我们写的注解:

package com.java.api;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;import com.java.api.UseCase.UseCases;/***解析注解:* * */
public class UserCaseTest {
public static void main(String[] args) {List<Integer> useCases = new ArrayList<Integer>();Collections.addAll(useCases, 47, 48, 49, 50);trackUseCases(useCases, PasswordUtils.class);
}
public static void trackUseCases(List<Integer> useCases, Class<?> cl) {for (Method m : cl.getDeclaredMethods()) {//获得注解的对象UseCases uc = m.getAnnotation(UseCases.class);if (uc != null) {System.out.println("Found Use Case:" + uc.id() + " "+ uc.description());useCases.remove(new Integer(uc.id()));}}for (int i : useCases) {System.out.println("Warning: Missing use case-" + i);}
}
}

总结:

java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。
注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中

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

其它

1、Annotation的工作原理:
JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型。该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的class文件和一个注解处理工具组成。Annotation并不直接影响代码的语义,但是他可以被看做是程序的工具或者类库。它会反过来对正在运行的程序语义有所影响。Annotation可以冲源文件、class文件或者在运行时通过反射机制多种方式被读取。2@Override注解:
java.lang
注释类型 Override
@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface Override
表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。@Override注解表示子类要重写父类的对应方法。Override是一个Marker annotation,用于标识的Annotation,Annotation名称本身表示了要给工具程序的信息。下面是一个使用@Override注解的例子:class A {private String id;A(String id){this.id = id;}@Overridepublic String toString() {return id;}
}
3@Deprecated注解:
java.lang
注释类型 Deprecated
@Documented
@Retention(value=RUNTIME)
public @interface Deprecated@Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。@Deprecated注解表示方法是不被建议使用的。Deprecated是一个Marker annotation。下面是一个使用@Deprecated注解的例子:class A {private String id;A(String id){this.id = id;}@Deprecatedpublic void execute(){System.out.println(id);}public static void main(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 @interface SuppressWarnings
指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。根据风格不同,程序员应该始终在最里层的嵌套元素上使用此注释,在那里使用才有效。如果要在特定的方法中取消显示某个警告,则应该注释该方法而不是注释它的类。@SuppressWarnings注解表示抑制警告。下面是一个使用@SuppressWarnings注解的例子:@SuppressWarnings("unchecked")
public static void main(String[] args) {List list = new ArrayList();list.add("abc");
}
5、自定义注解:
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。自定义最简单的注解:public @interface MyAnnotation {}
使用自定义注解:public class AnnotationTest2 {@MyAnnotationpublic void execute(){System.out.println("method");}
}
5.1、添加变量:
public @interface MyAnnotation {String value1();
}
使用自定义注解:public class AnnotationTest2 {@MyAnnotation(value1="abc")public void execute(){System.out.println("method");}
}
当注解中使用的属性名为value时,对其赋值时可以不指定属性的名称而直接写上属性值接口;除了value意外的变量名都需要使用name=value的方式赋值。5.2、添加默认值:
public @interface MyAnnotation {String value1() default "abc";
}
5.3、多变量使用枚举:
public @interface MyAnnotation {String value1() default "abc";MyEnum value2() default MyEnum.Sunny;
}
enum MyEnum{Sunny,Rainy
}
使用自定义注解:public class AnnotationTest2 {@MyAnnotation(value1="a", value2=MyEnum.Sunny)public void execute(){System.out.println("method");}
}
5.4、数组变量:
public @interface MyAnnotation {String[] value1() default "abc";
}
使用自定义注解:public class AnnotationTest2 {@MyAnnotation(value1={"a","b"})public void execute(){System.out.println("method");}
}
6、设置注解的作用范围:
@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Retention
指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。只有元注释类型直接用于注释时,Target 元注释才有效。如果元注释类型用作另一种注释类型的成员,则无效。public enum RetentionPolicy
extends Enum<RetentionPolicy>
注释保留策略。此枚举类型的常量描述保留注释的不同策略。它们与 Retention 元注释类型一起使用,以指定保留多长的注释。CLASS
编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。
RUNTIME
编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
SOURCE
编译器要丢弃的注释。
@Retention注解可以在定义注解时为编译程序提供注解的保留策略。属于CLASS保留策略的注解有@SuppressWarnings,该注解信息不会存储于.class文件。6.1、在自定义注解中的使用例子:
@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {String[] value1() default "abc";
}
7、使用反射读取RUNTIME保留策略的Annotation信息的例子:
java.lang.reflect接口 AnnotatedElement
所有已知实现类:AccessibleObject, Class, Constructor, Field, Method, Package
表示目前正在此 VM 中运行的程序的一个已注释元素。该接口允许反射性地读取注释。由此接口中的方法返回的所有注释都是不可变并且可序列化的。调用者可以修改已赋值数组枚举成员的访问器返回的数组;这不会对其他调用者返回的数组产生任何影响。如果此接口中的方法返回的注释(直接或间接地)包含一个已赋值的 Class 成员,该成员引用了一个在此 VM 中不可访问的类,则试图通过在返回的注释上调用相关的类返回的方法来读取该类,将导致一个 TypeNotPresentException。isAnnotationPresent
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。此方法主要是为了便于访问标记注释而设计的。参数:annotationClass - 对应于注释类型的 Class 对象返回:如果指定注释类型的注释存在于此对象上,则返回 true,否则返回 false抛出:NullPointerException - 如果给定的注释类为 null从以下版本开始:1.5getAnnotation
<T extends Annotation> T getAnnotation(Class<T> annotationClass)
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。参数:annotationClass - 对应于注释类型的 Class 对象返回:如果该元素的指定注释类型的注释存在于此对象上,则返回这些注释,否则返回 null抛出:NullPointerException - 如果给定的注释类为 null从以下版本开始:1.5getAnnotations
Annotation[] getAnnotations()
返回此元素上存在的所有注释。(如果此元素没有注释,则返回长度为零的数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。返回:此元素上存在的所有注释从以下版本开始:1.5getDeclaredAnnotations
Annotation[] getDeclaredAnnotations()
返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。返回:直接存在于此元素上的所有注释从以下版本开始:1.5下面是使用反射读取RUNTIME保留策略的Annotation信息的例子:自定义注解:@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {String[] value1() default "abc";
}
使用自定义注解:public class AnnotationTest2 {@MyAnnotation(value1={"a","b"})@Deprecatedpublic void execute(){System.out.println("method");}
}
读取注解中的信息:public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {AnnotationTest2 annotationTest2 = new AnnotationTest2();//获取AnnotationTest2的Class实例Class<AnnotationTest2> c = AnnotationTest2.class;//获取需要处理的方法Method实例Method method = c.getMethod("execute", new Class[]{});//判断该方法是否包含MyAnnotation注解if(method.isAnnotationPresent(MyAnnotation.class)){//获取该方法的MyAnnotation注解实例MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);//执行该方法method.invoke(annotationTest2, new Object[]{});//获取myAnnotationString[] 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 @interface Target
指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。 例如,此元注释指示该声明类型是其自身,即元注释类型。它只能用在注释类型声明上:@Target(ElementType.ANNOTATION_TYPE)public @interface MetaAnnotationType {...}
此元注释指示该声明类型只可作为复杂注释类型声明中的成员类型使用。它不能直接用于注释:@Target({}) public @interface MemberType {...}
这是一个编译时错误,它表明一个 ElementType 常量在 Target 注释中出现了不只一次。例如,以下元注释是非法的:@Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})public @interface Bogus {...}
public enum ElementType
extends Enum<ElementType>
程序元素类型。此枚举类型的常量提供了 Java 程序中声明的元素的简单分类。这些常量与 Target 元注释类型一起使用,以指定在什么情况下使用注释类型是合法的。ANNOTATION_TYPE
注释类型声明
CONSTRUCTOR
构造方法声明
FIELD
字段声明(包括枚举常量)
LOCAL_VARIABLE
局部变量声明
METHOD
方法声明
PACKAGE
包声明
PARAMETER
参数声明
TYPE
类、接口(包括注释类型)或枚举声明注解的使用限定的例子:@Target(ElementType.METHOD)
public @interface MyAnnotation {String[] value1() default "abc";
}
9、在帮助文档中加入注解:
要想在制作JavaDoc文件的同时将注解信息加入到API文件中,可以使用java.lang.annotation.Documented。在自定义注解中声明构建注解文档:@Documented
public @interface MyAnnotation {String[] value1() default "abc";
}
使用自定义注解:public class AnnotationTest2 {@MyAnnotation(value1={"a","b"})public void execute(){System.out.println("method");}
}
10、在注解中使用继承:
默认情况下注解并不会被继承到子类中,可以在自定义注解时加上java.lang.annotation.Inherited注解声明使用继承。@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Inherited
指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。

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

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

相关文章

2018.09.18 while循环

** "loop" 循环 注意要有引号。 **pass 过 #打印 1-100start 1 while start < 101:print("loop",start)start 1 #打印1-49&#xff0c;81-100. 60-80的平方start 1 while start <101 :if start >49 and start < 60:passelif start >5…

2019第二周作业

基础作业 实验代码 #include<stdlib.h> int main(void) {FILE*fp;int num[4],i,b,max;char op;if((fpfopen("c:\\tmj.txt","r"))NULL){ printf("File open error!\n"); exit(0);}for(i0;i<4;i){fscanf(fp,"%d%c",&nu…

实验一(高见老师收)

学 号201521450016 中国人民公安大学 Chinese people’ public security university 网络对抗技术 实验报告 实验一 网络侦查与网络扫描 学生姓名 陈璪琛 年级 2015 区队 五 指导教师 高见 信息技术与网络安全学院 2018年9月18日 实验任务总纲 2018—2019学年…

GitHub笔记(二)——远程仓库的操作

二 远程仓库 1 创建联系 第1步&#xff1a;创建SSH Key。在用户主目录下&#xff0c;看看有没有.ssh目录&#xff0c;如果有&#xff0c;再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件&#xff0c;如果已经有了&#xff0c;可直接跳到下一步。如果没有&#xff0c;打开S…

QT 子窗体 最大化 界面显示不对

QT 子窗体 最大化 复原 遇到的问题 项目中有个需求&#xff0c;主窗体中嵌套子窗体&#xff0c;需要将子窗体最大化显示和复原。 查了很多资料&#xff0c;基本上都是提到&#xff1a;QT中窗口部件QWidget成员函数showFullScreen();是用于将窗口部件全屏显示&#xff0c;但是他…

Spring 钩子之BeanFactoryPostProcessor和BeanPostProcessor

BeanFactoryPostProcessor和BeanPostProcessor这两个接口都是初始化bean时对外暴露的入口之一&#xff0c;和Aware类似&#xff08;PS:关于spring的hook可以看看Spring钩子方法和钩子接口的使用详解讲的蛮详细&#xff09;本文也主要是学习具体的钩子的细节&#xff0c;以便于实…

什么是HTML DOM对象

HTML DOM 对象 HTML DOM Document 对象 Document 对象 每个载入浏览器的 HTML 文档都会成为 Document 对象。 Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。 提示&#xff1a;Document 对象是 Window 对象的一部分&#xff0c;可通过 window.document 属…

Python3 matplotlib的绘图函数subplot()简介

Python3 matplotlib的绘图函数subplot()简介 一、简介 matplotlib下, 一个 Figure 对象可以包含多个子图(Axes), 可以使用 subplot() 快速绘制, 其调用形式如下 : subplot(numRows, numCols, plotNum) 图表的整个绘图区域被分成 numRows 行和 numCols 列 然后按照从左到右&…

signal(SIGHUP, SIG_IGN);

signal(SIGHUP, SIG_IGN); 的理解转载于:https://www.cnblogs.com/lanjiangzhou/p/10505653.html

spring钩子

Spring钩子方法和钩子接口的使用详解 前言 SpringFramework其实具有很高的扩展性&#xff0c;只是很少人喜欢挖掘那些扩展点&#xff0c;而且官方的Refrence也很少提到那些Hook类或Hook接口&#xff0c;至于是不是Spring官方有意为之就不得而知。本文浅析一下笔者目前看到的S…

【bitset 技巧 分块】bzoj5087: polycomp

神仙zq发现了${n^2\sqrt n}\over 32$做法 Description 你有三个系数为0,1的多项式f(x),g(x),h(x)求f(g(x)) mod h(x)为方便起见&#xff0c;将答案多项式所有系数对2取模输出即可如果f(x)Sigma(Ak * Xk)则f(g(x))Sigma(Ak(g(x))KInput 一共三行&#xff0c;每行一个多项式,分别…

day 012 生成器 与 列表推导式

生成器的本质就是迭代器&#xff0c;写法和迭代器不一样&#xff0c;用法一样。 获取方法&#xff1a; 1、通过生成器函数 2、通过各种推导式来实现生成器 3、通过数据的转换也可以获取生成器 例如&#xff1a; 更改return 为 yield 即成为生成器 该函数就成为了一个生成器函数…

数据库设计注意事项和原则

引言数据库设计是信息系统设计的基础&#xff0c;一个好的数据库设计在满足了软件需求之外&#xff0c;还要易维护、易扩充等等要求。当然&#xff0c;对专家们反复强调的数据的一致性、冗余性、访问效率等问题的解决&#xff0c;很大程度上取决于数据库设计者的经验和专业水平…

【AtCoder】ARC078

C - Splitting Pile 枚举从哪里开始分的即可 #include <bits/stdc.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar( ) #define enter putchar(\n) #define MAXN 200005 #defi…

20172325 2018-2019-1 《Java程序设计》第二周学习总结

20172325 2018-2019-1 《Java程序设计》第二周学习总结 教材学习内容总结 3.1集合 集合是一种聚集、组织了其他对象的对象。集合可以分为两大类&#xff1a;线性集合和非线性集合。线性集合&#xff1a;一种其元素按照直线方式组织的集合。非线性集合&#xff1a;一种其元素按某…

数据库视图

测试表:user有id&#xff0c;name&#xff0c;age&#xff0c;sex字段 测试表:goods有id&#xff0c;name&#xff0c;price字段 测试表:ug有id&#xff0c;userid&#xff0c;goodsid字段 视图的作用实在是太强大了&#xff0c;以下是我体验过的好处&#xff1a; 作用一&…

题解 luogu P2568 GCD

题解 luogu P2568 GCD 时间&#xff1a;2019.3.11 欧拉函数前缀和 题目描述 给定整数\(N\)&#xff0c;求\(1\le x,y \le N\)且\(\gcd(x,y)\)为素数的数对\((x,y)\)有多少对. 分析 枚举素数\(p\), 先求出\(1\le x,y \le \left \lfloor \dfrac n p \right \rfloor\)且\(\gcd(x, …

解决前后台发送请求或者接口之间发送请求乱码的问题

前后台传中文乱码&#xff1a; 前台使用encodeURI 进行编码 后台使用decode进行解码 如果接口之间调用出现乱码.接收方是&#xff1f;&#xff1f;&#xff1f;&#xff1f;这种。传送方式明文的处理方式&#xff1a; 发送方使用decode 进行编码&#xff1a; 接收方使用的ecod…

MSDN帮助文档 无法显示该网页 的问题解决方案(转)

MSDN帮助文档 "无法显示该网页" 的问题解决方案 以前就遇到过这样的问题&#xff0c;还以为是IE7导致的。后来重新安装了IE7也没有解决。后来就重新安装MSDN了&#xff0c;非常郁闷。今天终于知道原因了。因为开了HijackThis删除了一些注册协议&#xff0c;然后发现M…

.net Core发布至IIS完全手册带各种踩坑

服务器环境配置 和各位大爷报告一下我的服务器环境 : Windows Server 2012 iis 8 小插曲开始: 运维大哥在昨天给了我一台新的server 0环境开始搭建 。 并且没有安装任何的系统补丁。 第一件事情请开始打 补丁 打完补丁之后有时补丁会不完全 ,所以需要去官网获取补丁: KB2919355…