目录
1.定义Annotation类型
Annotation,也叫做注释,它的存在不影响程序正常运行,会对编译器警告或者其他辅助工具产生影响。
关键字是@interface
例如:
public @interface MemberAnnotation{
String value();
String describe() default "";
Class type();
}
注意:
- 代码块中就是大括号中方的是它的成员,其类型有String,Class,Primitive,enumerated,annotation,以及所列的类型数组。
- default是用来设置默认值的可以省略
2.Annotation的使用过程
在正常使用过程中通常还会用到@Target,@Retention
@Target是用来设置Annotation类型适用的程序元素种类,如果为设置则适用所有的程序元素
枚举常量 | 说明 |
---|---|
ANNOTATION_TYPE | 表示用于Annotation类型 |
TYPE | 表示用于类,接口和枚举,以及Annotation |
CONSTRUCTOR | 表示用于构造方法 |
FIELD | 表示用于成员变量和枚举变量 |
METHOD | 表示用于方法 |
PARAMETER | 表示用于参数 |
LOCAL_VARIABLE | 表示用于局部变量 |
PACKAGE | 表示用于包 |
@Retention可以设置Annotation的有效范围,如果没设置就是枚举常量CLASS表示范围
枚举常量 | 说明 |
---|---|
SOURCE | 表示不编译Annotation到类文件中,有效范围小 |
CLASS | 表示编译Annotation到类文件中,但是在运行是不加载Annotation到JVM中 |
RUNTIME | 表示在运行时加载Annotation到JVM中,有效范围最大 |
3.反射访问Annotation的方法
- @Retention中设置为RetentionPolicy.RUNTIME就能在运行中通过反射获的相关Annotation的信息
- Constructor,Field,Method都继承了AccessibleObject类,在这个类中有3个关于Annotation的方法
- isAnnotationPresent(Class<?extends Annotation>annotationClass)是用来查看是否添加了指定类型的Annotation,是就还回true,反之false
- getAnnotation(Class<?extends Annotation>annotationClass)用来获的指定的Annotation,存在就返回相应的对象,否则返回null
- getAnnotations()用来获的所有的Annotation,返回一个Annotation的数组
- Constructor,Method中还定义了getParameterAnnotations()用来访问参数添加的Annotation
4.应用实例
注释Constructor_Annotation代码:
package com.b.cn;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//用于构造方法
@Target(ElementType.CONSTRUCTOR)
//在运行中加载Annotation到JVM(java虚拟机)中
@Retention(RetentionPolicy.RUNTIME)
public @interface Constructor_Annotation {
//定义成员,有默认值的成员
String value() default "默认构造方法";
}
注释Feild_Method_Paramenter_Annotation代码:
package com.b.cn;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//用于字段参数方法
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER})
//在运行中加载Annotation到JVM(java虚拟机)中
@Retention(RetentionPolicy.RUNTIME)
public @interface Feild_Method_Paramenter_Annotation {
//定义成员
String describe();
Class type() default void.class;
}
Test类代码:
package com.b.cn;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
public class Test {
//注释字段
@Feild_Method_Paramenter_Annotation(describe = "编号",type = int.class)
int id;
@Feild_Method_Paramenter_Annotation(describe = "姓名",type = String.class)
String name;
//注释构造方法
@Constructor_Annotation()
public Test(){
}
@Constructor_Annotation("立即初始化构造方法")
public Test(
//注释方法参数
@Feild_Method_Paramenter_Annotation(describe = "编号",type = int.class)
int id,
@Feild_Method_Paramenter_Annotation(describe = "姓名",type = String.class)
String name
){
this.id=id;
this.name=name;
}
//注释方法
@Feild_Method_Paramenter_Annotation(describe = "获取编号",type = int.class)
public int getId(){
return id;
}
@Feild_Method_Paramenter_Annotation(describe = "设置编号")
public void setId(
@Feild_Method_Paramenter_Annotation(describe = "编号",type = int.class)
int id
){
this.id=id;
}
@Feild_Method_Paramenter_Annotation(describe = "获取姓名",type = String.class)
public String getName(){
return name;
}
@Feild_Method_Paramenter_Annotation(describe = "设置编号")
public void setName(
@Feild_Method_Paramenter_Annotation(describe = "编号",type = String.class)
String name
){
this.name=name;
}
public static void main(String[] args) {
//创建对象
Test test=new Test();
Test test1=new Test(12,"小明");
//创建Class对象
Class clsTest=test.getClass();
//反射获取构造方法
Constructor[] declaredConstructors=clsTest.getDeclaredConstructors();
for (Constructor c:declaredConstructors
) {
//是否为指定类型的注释
if (c.isAnnotationPresent(Constructor_Annotation.class)) {
//获得指定类型注释
Constructor_Annotation ca=(Constructor_Annotation) c.getAnnotation(Constructor_Annotation.class);
//获得指定类型注释信息
System.out.println(ca.value());
}
Annotation[][] parameterAnnotations=c.getParameterAnnotations();
for(int j=0;j<parameterAnnotations.length;j++){
int length=parameterAnnotations[j].length;
if(length==0){
System.out.println(" 未添加参数");
}else {
for (int k=0;k<length;k++){
Feild_Method_Paramenter_Annotation pa=(Feild_Method_Paramenter_Annotation) parameterAnnotations[j][k];
System.out.println(" "+pa.describe());
System.out.println(" "+pa.type());
}
}
System.out.println();
}
}
/*
System.out.println(test1.id);
System.out.println(test1.name);
*/
}
}
结果:
默认构造方法
立即初始化构造方法
编号
int
姓名
class java.lang.String