简介
Java注解是JDK1.5引入的一种注释机制,它不会改变编译器的编译方式,Java编译器对包含注解和不包含注解的代码会生成相同的Java虚拟机指令。在实际应用中,注解只是一种标识,具体的操作需要借助其他工具来解析和处理。
注解语法
注解是使用@interface来定义的,所有注解都隐式的扩展自java.lang.annotation.Annotation接口。
如下MyFirstAnnotation是一个自定义注解,它具有两个参数name和value,默认值都为空字符串。在它的定义之上还标注了@Retention和@Target两个元注解:
|
1 2 3 4 5 6 7 |
@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface MyFirstAnnotation { String name() default "" ;
String value() default "" ; } |
注解参数类型是有限制的,必须限制在以下几种类型中:
基本类型 String Class enum类型 注解类型 由前面所述类型组成的数组例如,如果不使用以上几种,则会出现编译错误:
|
1 2 3 4 5 6 7 |
@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface MyFirstAnnotation { String name() default "" ;
Integer value() default 1 ; //包装类型也不行,编译错误 } |
@Target和@Retention这种作用在注解上的注解,称之为元注解。常用的元注解如下:
1.@Target,用于标识注解可以标注的位置,接收一个ElementType[]参数。参数取值可以参考ElementType枚举类:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public enum ElementType { /** 类、接口(包括注释类型)或枚举声明 */ TYPE,
/** 字段声明(包括enum常量) */ FIELD,
/** 方法声明 */ METHOD,
/** 形参声明 */ PARAMETER,
/** 构造函数声明 */ CONSTRUCTOR,
/** 局部变量声明 */ LOCAL_VARIABLE,
/** 注解类型声明 */ ANNOTATION_TYPE,
/** 包声明 */ PACKAGE,
/** * 类型参数声明 * * @since 1.8 */ TYPE_PARAMETER,
/** * 任何类型名称 * * @since 1.8 */ TYPE_USE } |
当指定的@Target和注解的使用位置不匹配时就会出现编译错误,如下所示,@Target(ElementType.METHOD)表示MyFirstAnnotation注解只能用来标注方法,标注在类上就出现编译错误:
|
1 2 3 4 5 6 7 8 9 10 |
//编译错误 @MyFirstAnnotation public class Demo {
//正确 @MyFirstAnnotation public void doSomeThing(){ }
} |
2.@Retention,用于标识注解可以保留多久,接收一个RetentionPolicy参数,参数取值可以参考RetentionPolicy枚举类:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public enum RetentionPolicy { /** * 表示注解只会存在于.java的源代码文件中,不会保留到编译后的.class文件中 */ SOURCE,
/** * 表示注解可以保留到.class文件中,但是不会被Java虚拟机所加载 */ CLASS,
/** * 表示注解可以保留到.class文件中,并由虚拟机加载 */ RUNTIME } |
3.@Documented,表示这个注解能出现在javadoc中。
4.@Inherited,表示当这个注解用于一个类的时候,能够自动的被它的子类继承。
5.@Repeatable,表示这个注解可以在同一个位置应用多次。
默认情况下,同一个位置添加多个重复注解会有编译错误:
|
1 2 3 4 5 6 7 8 9 |
public class Demo { //编译错误 @MyFirstAnnotation (name = "张三" ) @MyFirstAnnotation (name = "李四" ) @MyFirstAnnotation (name = "王五" ) public void doSomeThing(){ }
} |
可以通过添加@Repeatable元注解来使@MyFirstAnnotation能重复使用。
首先需要创建一个容器注解@MyFirstAnnotations,容器注解@MyFirstAnnotations必须要有一个参数value,并且其类型为MyFirstAnnotation[]:
|
1 2 3 4 5 |
@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface MyFirstAnnotations { MyFirstAnnotation[] value(); } |
然后添加@Repeatable注解,并指定容器注解。
|
1 2 3 4 5 6 7 8 |
@Repeatable (MyFirstAnnotations. class ) @Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface MyFirstAnnotation { String name() default "" ;
String value() default "" ; } |
关于注解的使用需要注意,注解参数是不能为null的,默认值也是不能为null。
自定义注解测试
定义注解@RepeatMethod,包含int类型参数value。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Target (ElementType.METHOD) @Retention (RetentionPolicy.RUNTIME) public @interface RepeatMethod {
int value() default 1 ;
} |
在doSomeThing方法上应用注解。如果要指定的注解参数为value,并且没有指定其他的参数值时,可以采用简写的方式,省略参数名和等号。
|
1 2 3 4 5 6 |
public class Demo { @RepeatMethod ( 5 ) public void doSomeThing(){ System.out.println( "----注解测试----" ); } } |
通过反射获取注解信息,然后做对应的处理,如假设@RepeatMethod注解的作用是重复调用被标注的方法,参数value是指定重复调用方法的次数:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;
public class MyDemo { public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException { Class cla = Demo. class ; Method[] methods = cla.getMethods(); Object demo = cla.newInstance(); for (Method method : methods){ //判断方法上是否有标注@RepeatMethod注解 if (method.isAnnotationPresent(RepeatMethod. class )){ //获取RepeatMethod注解的参数值 RepeatMethod repeatMethod = method.getAnnotation(RepeatMethod. class ); for ( int i = 0 ;i < repeatMethod.value(); i++) method.invoke(demo, null ); } } } } |
输出结果:
|
1 2 3 4 5 |
----注解测试---- ----注解测试---- ----注解测试---- ----注解测试---- ----注解测试---- |
以上就是Java 注解学习笔记的详细内容,更多关于Java 注解的资料请关注其它相关文章!
原文链接:https://HdhCmsTestcnblogs测试数据/seve/p/14441203.html