java元注解有哪些(「Java基础」注解居然这么简单)java基础 / Java注解与元注解...

wufei123 发布于 2024-06-26 阅读(8)

Java 5开始,Java增加了元数据(MetaData)的支持,也就是Annotation(注解),注解可以理解为代码里的特殊标识,这些标识可以在编译、类加载、运行时被读取,并进行相应的处理通过Annotation,开发者可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。

Annotation是一个特殊的接口,程序可以通过反射来获取指定程序元素的Annotation对象,然后通过Annotation对象来取得注释里的元数据AnnotationJava提供的4个基本Annotation的用法——使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符使用,用于修饰它支持的程序元素。

java元注解有哪些(「Java基础」注解居然这么简单)java基础 / Java注解与元注解...

4个基本的Annotation如下:@Override:用来指定方法重写的,它可以强制一个子类必须覆盖父类的方法@Deprecated:用于表示某个程序元素(类、方法等)已过时,当其他程序使用已过时的类、方法时,编译器将会给出警告。

@SuppressWarnings:指示被该Annotation修饰的程序元素(以及该程序元素中的所有子元素)取消显示指定的编译器警告@SafeVarargs:是Java 7专门为抑制“堆污染”警告提供的(了解)。

元注解JDK除了在java.lang下提供了4个基本的Annotation之外,还在java.lang.annotation包下提供了4个Meta Annotation(元Annotation),这4个元Annotation都用于修饰其他的Annotation定义。

可以理解为在注解中使用的注解@Retention@Retention只能用于修饰一个Annotation定义,用于指定被修饰的Annotation可以保留多长时间,@Retention包含一个RetentionPolicy类型的value成员变量,所以使用@Retention时必须为该value成员变量指定值。

value成员变量的值只能是如下3个RetentionPolicy.CLASS:编译器将把Annotation记录在class文件中当运行Java程序时,JVM不再保留Annotation这是默认值RetentionPolicy.RUNTIME:编译器将把Annotation记录在class文件中。

当运行Java程序时,JVM也会保留Annotation,程序可以通过反射获取该Annotation信息RetentionPolicy.SOURCE:Annotation只保留在源代码中,编译器直接丢弃这种Annotation。

如果需要通过反射获取注释信息,就需要使用value属性值为RetentionPolicy.RUNTIME的@Retention使用@Retention元数据Annotation可采用如下代码为value指定值。

packagecn.bytecollege; importjava.lang.annotation.Retention; importjava.lang.annotation.RetentionPolicy

; @Retention(value = RetentionPolicy.RUNTIME) public @interface TestAnnotation { }如果Annotation里只有一个value成员变量,使用该Annotation时可以直接在Annotation后的括号里指定value成员变量的值,无须使用name=value的形式。

查看元注解@Retention源码可以发现@Retention注解中只有一个value属性:@Documented@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public

@interface Retention { /** * Returns the retention policy. * @return the retention policy */

RetentionPolicyvalue(); }因此在上例中的代码可以进行简写:packagecn.bytecollege; importjava.lang.annotation.Retention

; importjava.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation { }

@Target@Target也只能修饰一个Annotation定义,它用于指定被修饰的Annotation能用于修饰哪些程序单元@Target元Annotation也包含一个名为value的成员变量,该成员变量的值只能是如下几个。

ElementType.ANNOTATION_TYPE:指定该策略的Annotation只能修饰AnnotationElementType.CONSTRUCTOR:指定该策略的Annotation只能修饰构造器。

ElementType.FIELD:指定该策略的Annotation只能修饰成员变量ElementType.LOCAL_VARIABLE:指定该策略的Annotation只能修饰局部变量ElementType.METHOD:指定该策略的Annotation只能修饰方法定义。

ElementType.PACKAGE:指定该策略的Annotation只能修饰包定义ElementType.PARAMETER:指定该策略的Annotation可以修饰参数ElementType.TYPE:指定该策略的Annotation可以修饰类、接口(包括注释类型)或枚举定义。

与使用@Retention类似的是,使用@Target也可以直接在括号里指定value值,而无须使用name=value的形式packagecn.bytecollege; importjava.lang

.annotation.ElementType; importjava.lang.annotation.Retention; importjava.lang.annotation.RetentionPolicy

; importjava.lang.annotation.Target; @Retention(value = RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface TestAnnotation { }

@Documented@Documented用于指定被该元Annotation修饰的Annotation类将被javadoc工具提取成文档,如果定义Annotation类时使用了@Documented修饰,则所有使用该Annotation修饰的程序元素的API文档中将会包含该Annotation说明。

packagecn.bytecollege; importjava.lang.annotation.Documented; importjava.lang.annotation.ElementType

; importjava.lang.annotation.Retention; importjava.lang.annotation.RetentionPolicy; importjava.lang.annotation

.Target; @Retention(value = RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public @interface TestAnnotation { }

@Inherited@Inherited元Annotation指定被它修饰的Annotation将具有继承性——如果某个类使用了@A Annotation(定义该Annotation时使用了@Inherited修饰)修饰,则其子类将自动被@A修饰。

packagecn.bytecollege; importjava.lang.annotation.Documented; importjava.lang.annotation.ElementType

; importjava.lang.annotation.Inherited; importjava.lang.annotation.Retention; importjava.lang.annotation

.RetentionPolicy; importjava.lang.annotation.Target; @Retention(value = RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Inherited public @interface TestAnnotation { }

自定义注解定义新的Annotation类型使用@interface关键字(在原有的interface关键字前增加@符号)定义一个新的Annotation类型与定义一个接口非常像,如下代码可定义一个简单的Annotation类型。

public @interfaceTest{ }定义了该Annotation之后,因为没有指定@Rentention,因此就可以在程序的任何地方使用该Annotation在默认情况下,Annotation可用于修饰任何程序元素,包括类、接口、方法等。

Annotation不仅可以是这种简单的Annotation,还可以带成员变量,Annotation的成员变量在Annotation定义中以无形参的方法形式来声明,其方法名和返回值定义了该成员变量的名字和类型。

如下代码可以定义一个有成员变量的Annotationpublic @interfaceMyAnno{ String name(); intage(); }一旦在Annotation里定义了成员变量之后,使用该Annotation时就应该为该Annotation的成员变量指定值,如下代码所示。

package cn.bytecollege; @MyAnno(name="张三",age=18)publicclassStudent{ } 也可以在定义Annotation的成员变量时为其指定初始值(默认值),指定成员变量的初始值可使用default关键字。

如下代码定义了@MyAnno Annotation,该Annotation里包含了两个成员变量:name和age,这两个成员变量使用default指定了初始值package cn.bytecollege;

public @interfaceMyAnno{ String name() default "张三"; intage() default 18; }如果为Annotation的成员变量指定了默认值,使用该Annotation时则可以不为这些成员变量指定值,而是直接使用默认值。

获取Annotation的信息当开发者使用Annotation修饰了类、方法、Field等成员之后,这些Annotation不会自己生效,必须由开发者提供相应的工具来提取并处理Annotation信息Java使用Annotation接口来代表程序元素前面的注释,该接口是所有Annotation类型的父接口。

Java 5在java.lang.reflect包下新增了AnnotatedElement接口,该接口代表程序中可以接受注释的程序元素该接口主要有如下几个实现类Class:类定义Constructor:构造器定义。

Field:类的成员变量定义Method:类的方法定义Package:类的包定义AnnotatedElement接口是所有程序元素(如Class、Method、Constructor等)的父接口,所以程序通过反射获取了某个类的AnnotatedElement对象(如Class、Method、Constructor等)之后,程序就可以调用该对象的如下3个方法来访问Annotation信息。

getAnnotation(ClassannotationClass):返回该程序元素上存在的指定类型的注释,如果该类型的注释不存在,则返回nullAnnotation[]getAnnotations():返回该程序元素上存在的所有注释。

boolean isAnnotationPresent(ClassannotationClass):判断该程序元素上是否存在指定类型的注释,如果存在则返回true,否则返回false。

获取注解在下面的示例中,结合自定义注解,获取Class上的注解package cn.bytecollege.anno; import java.lang.annotation.Annotation;

import java.lang.reflect.Field; import java.lang.reflect.Method; publicclassGetAnnotation{ public static void main(String[] args) throws NoSuchFieldException, SecurityException { Class clazz = Student

.class;//获取类上的注解 Annotation[] annotations1 = clazz.getDeclaredAnnotations(); for (Annotation annotation

: annotations1) { System.out.println(annotation); } //获取成员变量上的注解 Field field = clazz.getDeclaredField(

"name"); Annotation[] annotations2 = field.getAnnotations(); for (Annotation annotation : annotations2) { System.

out.println(annotation); } //获取方法上的注解 Annotation[] annotations3 = clazz.getAnnotations();

for (Annotation annotation : annotations3) { System.out.println(annotation); } } }

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

河南中青旅行社综合资讯 奇遇综合资讯 盛世蓟州综合资讯 综合资讯 游戏百科综合资讯 新闻99880