首页 > 编程知识 正文

java开发中的注解自定义详解,java注解的使用

时间:2023-05-06 08:38:52 阅读:33321 作者:4553

1注释的定义和用途

1.1官方说明

An annotation is a form of metadata,that can be added to Java source code。

Classes、methods、variables、parametersandpackagesmaybeannotated。

annotationshavenodirecteffectontheoperationofthecodetheyannotate。

注释是可以添加到java代码中的元数据,它是类似于类、接口、数组和枚举的java数据类型

类、方法、变量、参数和包可以用注释限定

注释不会直接影响限定的代码

1.2用途

Annotations have a number of uses,among them:

informationforthecomplier-annotationscanbeusedbythecompilertodetecterrorsorsuppresswarnings。

compiler-timeanddeployment-time processing-softwaretoolscanprocessannotationtogeneratecode,XML files,andsoff

运行时处理- someannotationsareavailabletobeexaminedatruntime。

向编译器提供信息:编译器可以使用注释来检测错误和抑制警告

编译和部署时的处理:软件工具可以处理注释信息并生成代码、XML文件等

运行时处理:有些注释可以在运行时检查

2使用自定义注释

注释是标记程序代码中的关键点(类、方法、变量、参数和包)的标记,程序可以在编译或运行时检测到这些点并执行特殊操作

基本步骤

定义注释

设置注释并标记所需的代码

分析注释在编译或运行时检测标记并执行特殊操作

2.1注释的定义

1 //@CherryAnnotation仅限于方法,在运行时有效

2 @ retention (retention policy.runtime )3@target ) value={elementtype.method} )4public @ interfacecherryanotion

5公共字符串name (; 6 int age ) ) default 18; 7 int[] array (; 8 }

声明注释类型:使用关键字@interface时,在基本实现中,所有定义的注释都会自动继承Java.lang.annotation.annotation接口。

注释性实现部分:只能定义注释性元素

注释元素的使用注意事项:

a .访问修饰符必须是公共的,不写的默认值是公共的;

b .该元素的类型只能是基本数据类型、字符串、类、枚举类型、注释类型和数组;

c .元素名称一般定义为名词,如果注释中只有一个元素,则名称可以为value

d.) )是特殊语法,不能定义参数

e.default是默认值,必须与定义类型匹配

f .如果没有默认值,这意味着以后使用注释时必须为类型更改元素赋值

元注释:修饰注释的注释

@Target注释用于限制可以应用特定自定义注释的Java元素。 使用枚举类型定义如下:

1公共枚举类型{2/* *类、接口(包括注释类型)或枚举的声明) /

3类型,4

5 /**属性的声明*/

6个字段,7

8 /**方法声明*

9方法,10

11 /**方法格式参数声明*

12参数,13

14 /**构建方法声明*

15构造器,16

17 /**局部变量宣言*/

18 LOCAL_VARIABLE,19

20 /**评论类型声明*

21 ANNOTATION_TYPE,22

23 /**包声明*

24包25 }

@Retention注释用于限定自定义注释的生命力。

评论的生命周期有三个阶段。 1、Java源文件阶段; 2、编译成class文件阶段3、运行时间表

段。RetentionPolicy枚举类型

1 public enumRetentionPolicy {2 /**

3 * Annotations are to be discarded by the compiler.4 * (注解将被编译器忽略掉)5 * 将被限定在Java源文件中,这个注解即不会参与编译也不会在运行期起任何作用,就和注释是一样的效果,只能被阅读Java文件的人看到;6 */

7 SOURCE,8

9 /**

10 * Annotations are to be recorded in the class file by the compiler11 * but need not be retained by the VM at run time. This is the default12 * behavior.13 * (注解将被编译器记录在class文件中,但在运行时不会被虚拟机保留,这是一个默认的行为)14 * 将被编译到Class文件中,编译器可以在编译时根据注解做一些处理动作,但是运行时JVM(Java虚拟机)会忽略它,我们在运行期也不能读取到;15 */

16 CLASS,17

18 /**

19 * Annotations are to be recorded in the class file by the compiler and20 * retained by the VM at run time, so they may be read reflectively.21 * (注解将被编译器记录在class文件中,而且在运行时会被虚拟机保留,因此它们能通过反射被读取到)22 * 注解可以在运行期的加载阶段被加载到Class对象中。在程序运行阶段,我们可以通过反射得到这个注解,并通过判断是否有这个注解或这个注解中属性的值,23 * 从而执行不同的程序代码段。我们实际开发中的自定义注解几乎都是使用的RetentionPolicy.RUNTIME;24 *@seejava.lang.reflect.AnnotatedElement25 */

26 RUNTIME27 }

@Documented注解,是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中。

@Inherited注解,是指定某个自定义注解如果写在了父类的声明部分,那么子类的声明部分也能自动拥有该注解。@Inherited注解只对那些@Target被定义为ElementType.TYPE的自定义注解起作用。

2.2 配置注解  把标记打在需要用到的代码中

1 public classStudent {2 @CherryAnnotation(name = "cherry-peng",age = 23,score = {99,66,77})3 public void study(inttimes){4 for(int i = 0; i < times; i++){5 System.out.println("Good Good Study, Day Day Up!");6 }7 }8 }

在定义的注解中,有些注解类型元素没有默认值,使用的时候需要在标记名后面加上(),并以“元素名1=元素值1,元素名2=元素值=2”的形式为元素赋值。(原有默认的会被覆盖)

2.3 解析注解  在编译时或运行时检测到标记,并进行特殊操作

只有当注解的保持力处于运行阶段,即使用@Retention(RetentionPolicy.RUNTIME)修饰注解时,才能在JVM运行时,检测到注解,并进行一系列特殊操作。

反射操作获取注解

public classTestAnnotation {public static voidmain(String[] args){try{//获取Student的Class对象

Class stuClass = Class.forName("pojos.Student");//说明一下,这里形参不能写成Integer.class,应写为int.class

Method stuMethod = stuClass.getMethod("study",int.class);//判断该元素上是否配置有某个指定的注解

if(stuMethod.isAnnotationPresent(CherryAnnotation.class)){

System.out.println("Student类上配置了CherryAnnotation注解!");//获取该元素上指定类型的注解

CherryAnnotation cherryAnnotation = stuMethod.getAnnotation(CherryAnnotation.class);

System.out.println("name: " + cherryAnnotation.name() + ", age: " +cherryAnnotation.age()+ ", score: " + cherryAnnotation.score()[0]);

}else{

System.out.println("Student类上没有配置CherryAnnotation注解!");

}

}catch(ClassNotFoundException e) {

e.printStackTrace();

}catch(NoSuchMethodException e) {

e.printStackTrace();

}

}

}//getAnnotations(),该方法可以获得该对象身上配置的所有的注解,返回Annotation类型数组

特殊语法

1.如果注解本身没有注解类型元素,在使用注解的时候可以省略(),直接写为:@注解名,它和标准语法@注解名()等效

1 @Retention(RetentionPolicy.RUNTIME)2 @Target(value ={ElementType.TYPE})3 @Documented4 public @interfaceFirstAnnotation {5 }6 ------------------------------------

7 //等效于@FirstAnnotation()

8 @FirstAnnotation9 public classJavaBean{10 //省略实现部分

11 }

2.如果注解本本身只有一个注解类型元素,而且命名为value,在使用注解的时候可以直接使用:@注解名(注解值),其等效于:@注解名(value = 注解值)

@Retention(RetentionPolicy.RUNTIME)

@Target(value={ElementType.TYPE})

@Documentedpublic @interfaceSecondAnnotation {

String value();

}------------------------------------

//等效于@ SecondAnnotation(value = "this is second annotation")

@SecondAnnotation("this is annotation")public classJavaBean{//省略实现部分

}

3.如果某个注解类型元素是一个数组类型,在使用时又只需要填入一个值的情况,在使用注解时可以直接写为:@注解名(类型名 = 类型值),它和标准写法:@注解名(类型名 = {类型值})等效

@Retention(RetentionPolicy.RUNTIME)

@Target(value={ElementType.TYPE})

@Documentedpublic @interfaceThirdAnnotation {

String[] name();

}--------------------------------------

//等效于@ ThirdAnnotation(name = {"this is third annotation"})

@ ThirdAnnotation(name = "this is third annotation")public classJavaBean{//省略实现部分

}

4.如果一个注解的@Target是定义为Element.PACKAGE,这个注解是配置在package-info.java中的,而不能直接在某个类的package代码上面配置。

Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。

作用在代码的注解是

1 @Override -检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。2 @Deprecated -标记过时方法。如果使用该方法,会报编译警告。3 @SuppressWarnings -指示编译器去忽略注解中声明的警告。4 作用在其他注解的注解(或者说 元注解)是:5 @Retention -标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。6 @Documented -标记这些注解是否包含在用户文档中。7 @Target -标记这个注解应该是哪种 Java 成员。8 @Inherited -标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)9 从 Java 7 开始,额外添加了 3个注解:10 @SafeVarargs - Java 7开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。11 @FunctionalInterface - Java 8开始支持,标识一个匿名函数或函数式接口。12 @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。