当前位置:首页 > 编程笔记 > 正文
已解决

Java--Class类与反射+Annotation注解

来自网友在路上 172872提问 提问时间:2023-10-31 05:24:59阅读次数: 72

最佳答案 问答题库728位专家为你答疑解惑

        通过Java的反射机制,可以在程序中访问已经装载到JVM中的Java对象的描述,实现访问、检测、修改描述Java对象本身信息的功能。java.lang.reflect包提供了反射的支持。

1.获取对象的类的对象:Class 类对象名 = 对象.getClass()

Class 类对象名 = 对象.getClass()

类对象通过反射可以访问的主要描述信息:

通过反射可访问的主要描述信息 组成部分访问方法返回值类型说明访问包路径getPackage()Package对象获得该类的存放路径访问类名称getName()String对象获得该类的名称访问继承类getSuperclass()Class对象获得该类继承的类访问实现接口getInterfaces()Class型数组获得该类实现的所有接口访问构造方法getConstructors()Constructor型数组获得所有权限为public的构造方法getConstructors(Class<?>...parameterTypes)Constructor对象获得指定的权限为public的构造方法getDeclaredConstructors()Constructor型数组获得所有构造方法,按照声明顺序返回getDeclaredConstructors(Class<?>...parameterTypes)Constructor对象获取指定构造方法访问方法getMethods()Method型数组获取所有权限为public的方法getMethod(String name, Class<?>...parameterTypes)Method对象获得指定的权限为public的方法getDeclaredMethods()Method型数组获得所有的方法,按声明顺序返回getDeclaredMethod(String name, Class<?>...parameterTypes)Method对象获得指定的方法访问成员变量getFields()Field型数组获得所有权限为public的成员变量getField(String name)Field对象获得指定的权限为public的成员变量getDeclaredFields()Field型数组获得所有的成员变量,按声明顺序返回getDeclaredField(String name)Field对象获得指定的成员变量访问内部类getClasses()Class型数组获得所有权限为public的内部类getDeclaredClasses()Class型数组获得所有内部类访问内部类的声明类getDeclaringClass()Class对象如果该类为内部类,则返回他的成员类,否则返回null

        Tips:

        getFields()和getMethods()方法获取的成员变量和方法,包括从超类中继承到的成员变量和方法。而getDeclaredFields()方法和getDeclaredMethods()方法,只会获取本类中定义的所有成员变量和方法。 

 2.访问构造方法

2.1 getConstructors()

2.2 getConstructor(Class<?>...parameterTypes)

2.3 getDeclaredConstructors()

2.4 getDeclaredConstructor(Class<?>...parameterTypes)

如果访问指定的构造方法,需要根据构造方法的参数类型来访问,如

objectClass.getDeclaredConstructor(String.class, int.class);

objectClass.getDeclaredConstructor(new Class[]{String.class, int.class})

Constructor类常用方法 方法返回值类型说明isVarArgs()boolean判断该构造方法是否允许带可变数量的参数,如果允许,返回true,反之返回falsegetParameterTypes()Class型数组获得该构造方法的各个参数类型getExceptionTypes()Class型数组获得该构造方法可能抛出的异常类型newInstance(Object...initargs)类的对象通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数,则采用默认的无参数构造方法setAccessible(boolean flag)void如果该构造方法为private修饰,则不允许通过反射利用newInstance(Object...initargs)方法创建对象。如果先执行了此方法,并将入口参数设为true,则允许创建getModifiers()int获得该构造方法所采用修饰符的个数

        Tips:        

        通过.java.lang.reflect.Modifier类可以解析出getModifiers()方法的返回值所表示的修饰符信息;在该类中提供了以下列的静态方法,既可以查看是否被指定的修饰符修饰,也可以以字符串的形式获得所有修饰符。

Modifier类中的常用解析方法 静态方法说明isPublic(int mod)查看是否被public修饰isProtected(int mod)查看是否被protected修饰isPrivate(int mod)查看是否被private修饰isStatic(int mod)查看是否被static修饰isFinal(int mod)查看是否被final修饰toString(int mod)以字符串的形式返回所有修饰符

        Tips:

        参数(int mod)中的mod,即Constructor类中的getModifiers()方法的返回值。

int mod = constructor.getModifiers();

boolean isEmbellishByPrivate = Modifier.isPrivate(mod);

String embellishment = Modifier.toString(mod);

Example_o1.java: 

package reflectdemo;public class Example_01 {String s;int i, i2, i3;private Example_01() {}protected Example_01(String s, int i) {this.s = s;this.i = i;}public Example_01(String... strings) {if (strings.length > 0) {i = Integer.valueOf(strings[0]);}if (strings.length > 1) {i2 = Integer.valueOf(strings[1]);}if (strings.length > 2) {i3 = Integer.valueOf(strings[2]);}}public void print() {System.out.println("s=" + s);System.out.println("i=" + i);System.out.println("i2=" + i2);System.out.println("i3=" + i3);}}

 Main_01.java:

package reflectdemo;import java.lang.reflect.Constructor;public class Main_01 {public static void main(String[] args) {Example_01 example = new Example_01("10", "20", "30");Class exampleC = example.getClass();//获取所有构造方法Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();for (int x = 0; x < declaredConstructors.length; x++) {Constructor constructor = declaredConstructors[x];boolean is_vars_args = constructor.isVarArgs();     //判断此构造方法是否允许带有可变数量参数System.out.println("构造方法是:" + constructor);System.out.println("查看是否允许带有可变数量参数:" + is_vars_args);System.out.println("该构造方法的入口参数类型依次是:");Class[] parameterTypes = constructor.getParameterTypes();   //获取该构造方法的各个参数类型for (int j = 0; j < parameterTypes.length; j++) {System.out.println(" " + parameterTypes[j]);}Class[] exceptionTypes = constructor.getExceptionTypes();     //获取所有该构造方法可能抛出的异常for (int k = 0; k < exceptionTypes.length; k++) {System.out.println("该构造方法可能抛出的异常类型有:" + exceptionTypes[k]);}Example_01 example2 = null;while (example2 == null) {try {if (x == 2)     //此处访问无参数的构造方法example2 = (Example_01) constructor.newInstance();else if (x == 1)    //此处访问参数为字符串和整型的构造方法example2 = (Example_01) constructor.newInstance("7", 5);else {      //此处访问参数为数组的构造方法Object[] parameters = new Object[]{new String[]{"100", "200", "300"}};example2 = (Example_01) constructor.newInstance(parameters);}} catch (Exception e) {System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法:");constructor.setAccessible(true);}}if (example2 != null) {example2.print();System.out.println();}}}
}输出:构造方法是:public reflectdemo.Example_01(java.lang.String[])查看是否允许带有可变数量参数:true该构造方法的入口参数类型依次是:class [Ljava.lang.String;s=nulli=100i2=200i3=300构造方法是:protected reflectdemo.Example_01(java.lang.String,int)查看是否允许带有可变数量参数:false该构造方法的入口参数类型依次是:class java.lang.Stringints=7i=5i2=0i3=0构造方法是:private reflectdemo.Example_01()查看是否允许带有可变数量参数:false该构造方法的入口参数类型依次是:在创建对象时抛出异常,下面执行setAccessible()方法:s=nulli=0i2=0i3=0

3.访问成员变量

        通过以下方法访问成员变量时,将返回Field类型的对象或数组;每个Field对象代表一个成员变量,利用这些Field对象可以操作相应的成员变量。

3.1 getFields()

3.2 getField(String name)

3.3 getDeclaredFields()

3.4 getDeclaredField(String name)

访问指定的成员变量birthday:

Example_01 example = new Example_01("10", "20", "30");
Class exampleC = example.getClass();
//获取所有构造方法
Field birthdy_field = exampleC.getDeclaredField("birthday");

Field类中提供的常用方法

Field类的常用方法 方法返回值类型说明getName()String获取该成员变量的名称getType()Class对象获取该成员变量的类型get(Object obj)Object型获取指定对象Object中成员变量的值set(Object obj, Object value)void将指定对象obj中的成员变量的值设置为valuegetInt(Object obj)int获得指定对象obj中类型为int的成员变量的值setInt(Object obj, int value)void将指定对象obj中类型为int的成员变量的值设置为valuegetFloat(Object obj)float获得指定对象obj中类型为float的成员变量的值setFloat(Object obj,float value)void将指定对象obj中类型为float的成员变量的值设置为valuegetBoolean(Object obj)boolean获得指定对象obj中类型为boolean的成员变量的值setBoolean(Object obj, boolean value)void将指定对象obj中类型为boolean的成员变量的值设置为valuesetAccessible(boolean flag)void此方法可以设置是否忽略权限限制直接访问private等私有权限的成员变量getModifers()int获得该成员变量被解析出的修饰符的整数

Example_02.java: 

package reflectdemo;public class Example_02 {int i;public float f;protected boolean b;private String s;
}

Main_02.java: 

package reflectdemo;import java.lang.reflect.Field;public class Main_02 {public static void main(String[] args) {Example_02 example = new Example_02();Class exampleC = example.getClass();//获得所有成员变量Field[] declaredFields = exampleC.getDeclaredFields();for (int a = 0; a < declaredFields.length; a++) {     //遍历成员变量Field field = declaredFields[a];System.out.println("名称为:" + field.getName());     //获得成员变量名称Class fieldType = field.getType();      //获得成员变量类型System.out.println("类型为:" + fieldType);boolean isTurn = true;while (isTurn) {try {isTurn = false;//如果该成员变量的访问权限为private,则抛出异常,不允许访问System.out.println("修改前的值为:" + field.get(example));if (fieldType.equals(int.class)) {System.out.print("利用方法setInt()修改成员变量的值:");field.setInt(example, 165);      //为int型成员变量赋值} else if (fieldType.equals(float.class)) {System.out.print("利用setFloat()方法修改成员变量:");field.setFloat(example, 99.90f);} else if (fieldType.equals(boolean.class)) {System.out.print("利用setBoolean()方法修改成员变量:");field.setBoolean(example, true);} else {System.out.print("利用set()方法修改成员变量的值:");field.set(example, "春田");}//获取修改后的成员变量的值System.out.println(field.get(example));} catch (Exception e) {System.out.println("设置成员变量时抛出异常," + "下面执行setAccessible()方法!");field.setAccessible(true);      //设置为允许访问isTurn = true;}}System.out.println("----------");}}
}输出:名称为:i类型为:int修改前的值为:0利用方法setInt()修改成员变量的值:165----------名称为:f类型为:float修改前的值为:0.0利用setFloat()方法修改成员变量:99.9----------名称为:b类型为:boolean修改前的值为:false利用setBoolean()方法修改成员变量:true----------名称为:s类型为:class java.lang.String设置成员变量时抛出异常,下面执行setAccessible()方法!修改前的值为:null利用set()方法修改成员变量的值:春田----------

4.访问方法

        利用下面的方法访问方法时,将返回Method类型的对象或数组。每个Method对象代表一个方法,利用Method对象可以操作相应的方法。

4.1 getMethods()

4.2 getMethod(String name, Class<?>...parameterTypes)

4.3 getDeclaredMethods()

4.4 getDeclaredMethod(String name, Class<?>...parameterTypes)

        如果访问指定的方法,需要根据该方法的名称和入口参数类型来访问。

1. objectClass.getDeclaredMethod("print", String.class, int.class)

2. objectClass.getDeclaredMethod("print", new Class[] {String.class, int.class})

Example_02 example = new Example_02();
Class exampleC = example.getClass();
//获得所有成员方法
Method[] declaredFields = exampleC.getDeclaredMethods();
Method类的常用方法 方法返回值类型说明getName()String获取方法名称getParamterTypes()Class型数组按照声明顺序获取方法各个参数类型getReturnType()Class型数组获取该方法的返回值类型getExceptionType()Class型数组获取该方法可能抛出的异常类型invoke(Object obj, Object...args)Object型利用指定参数args执行指定对象中的该方法isVarArgs()boolean判断该方法是否允许使用可变数量的参数,允许返回true,反之返回falsesetAccessible(boolean flag)void此方法可以设置是否忽略权限限制直接访问private等私有权限的成员变量getModifiers()int获得该成员变量被解析出的修饰符的整数

Example_03.java:

package reflectdemo;public class Example_03 {static void staticMethod() {System.out.println("执行staticMethod()方法");}public int publicMethod(int i) {System.out.println("执行publicMethod()方法");return i * 100;}protected int protectedMethod(String s, int i) throws NumberFormatException {System.out.println("执行protectedMethod()方法");return Integer.valueOf(s) + i;}private String privateMethod(String... strings) {System.out.println("执行privateMethod()方法");StringBuffer stringBuffer = new StringBuffer();     //StringBuffer线程安全,StringBuilder线程不安全for (int i = 0; i < strings.length; i++) {stringBuffer.append(strings[i]);}return stringBuffer.toString();}
}

Main_03.java:

package reflectdemo;import java.lang.reflect.Method;public class Main_03 {public static void main(String[] args) {Example_03 example = new Example_03();Class exampleC = example.getClass();Method[] declaredMethods = exampleC.getDeclaredMethods();for (int m = 0; m < declaredMethods.length; m++) {Method method = declaredMethods[m];System.out.println("名称为:" + method.getName());       //获得方法名称System.out.println("是否允许带有可变数量的参数:" + method.isVarArgs());System.out.println("入口参数类型依次为:");Class[] parameterTypes = method.getParameterTypes();    //获得所有参数类型for (int c = 0; c < parameterTypes.length; c++) {System.out.println(parameterTypes[c]);}System.out.println("获得方法的返回值类型是:" + method.getReturnType());  //获取方法的返回值类型System.out.println("方法可能抛出的异常有:");Class[] exceptionTypes = method.getExceptionTypes();        //获取方法可能抛出的异常类型for (int e = 0; e < exceptionTypes.length; e++) {System.out.println(" " + exceptionTypes[e]);}boolean isTurn = true;while (isTurn) {isTurn = false;//如果该方法的访问权限为private,则抛出异常,即不允许访问,需要setAccessible()方法修改权限try {if (method.getName().equals("staticMethod")) {method.invoke(example);     //执行没有入口参数的方法} else if ("publicMethod".equals(method.getName())) {System.out.println(method.invoke(example, 165));     //执行有1个int型参数的方法} else if (method.getName().equals("protectedMethod")) {System.out.println(method.invoke(example, "7", 5));       //执行1个String型参数和1个int型参数的方法} else {Object[] parameters = new Object[][]{new String[]{"M", "W", "Q"}};String returnValues = (String) method.invoke(example, parameters);System.out.println("返回值是:" + returnValues);}} catch (Exception e) {System.out.println("执行setAccessible()方法!");method.setAccessible(true);isTurn = true;}}System.out.println("----------");}}
}输出:名称为:staticMethod是否允许带有可变数量的参数:false入口参数类型依次为:获得方法的返回值类型是:void方法可能抛出的异常有:执行staticMethod()方法----------名称为:publicMethod是否允许带有可变数量的参数:false入口参数类型依次为:int获得方法的返回值类型是:int方法可能抛出的异常有:执行publicMethod()方法16500----------名称为:protectedMethod是否允许带有可变数量的参数:false入口参数类型依次为:
class java.lang.Stringint获得方法的返回值类型是:int方法可能抛出的异常有:
class java.lang.NumberFormatException执行protectedMethod()方法12----------名称为:privateMethod是否允许带有可变数量的参数:true入口参数类型依次为:
class [Ljava.lang.String;获得方法的返回值类型是:class java.lang.String方法可能抛出的异常有:执行setAccessible()方法!执行privateMethod()方法返回值是:MWQ----------

5.使用Annotation注解功能

Java中Annotation注解功能,可用于类、构造方法、成员变量、方法、参数等的声明中,该功能不影响程序的运行,但是会对编译器警告等辅助工具产生影响。

5.1 定义Annotation类型:@interface

        @interface关键字隐含的意思就是继承java.lang.annotation.Annotation接口。

5.1.1 无任何成员marker annotation

public @interface noMemberAnnotation{

        //无任何成员

}

5.1.2 有成员annotation

public @interface OneMemberAnnotation{

        String value();

}

String:成员类型。可用的成员类型有:String ,Class,primitive,enumerated,annotation,以及这些所列类型的数组。

value:成员名称。如果所定义的Annotation注解中只有一个成员,通常这个成员被命名为value.

5.1.3 成员有默认值的annotation

public @interface DefaultValueAnnotation{

        String describe() default "默认值";

        Class type() default void.class;

}

5.2 @Target设置Annotation类型适用的程序元素种类

        如果我们的注解未设置@Target,则表示这个注解适用于所有程序元素。@Target的值通常是枚举类ElementType中的枚举常量。

枚举类ElementType中的枚举常量 枚举常量说明ElementType.ANNOTATION_TYPE表示用于Annotation类型ElementType.TYPE表示用于类、接口、枚举、Annotation类型ElementType.CONSTRUCTOR表示用于构造方法ElementType.FIELD表示用于成员变量和枚举常量ElementType.METHOD表示用于方法ElementType.PARAMETER表示用于参数ElementType.LOCAL_VARIABLE表示用于局部变量ElementType.PACKAGE表示用于包

5.3 @Retention设置Annotation类型的有效范围

        通过@Retention可以设置我们Annotation注解的有效范围。如果我们的注解未设置@Retention,则这个注解的有效范围为枚举常量CLASS表示的范围。通常我们使用枚举类RetentionPolicy中的枚举常量来设置@Retention的值。

枚举类RetentionPolicy中的枚举常量 枚举常量说明RetentionPolicy.SOURCE表示不编译Annotaion注解到类文件中,范围最小RetentionPolicy.CLASS表示编译Annotation注解到类文件中,但是在运行时不加载Annotation到JVM中RetentionPolicy.RUNTIME表示在运行时加载Annotation到JVM中,有效范围最大

5.4 访问Annotation信息

        只要在定义Annotation注解类时将@Retention设置为RetentionPolicy.RUNTIMT,那么在运行程序时就可以通过反射获取到相关的Annotation注解信息,如获得构造方、字段、方法的Annotation信息。

5.4.1 isAnnotationPresent(Class<? extends Annotation> annotationClass)方法

         查看对象是否添加了指定的annotation注解,返回boolean值。

5.4.2 getAnnotation(Class<T> annotionClass)方法

         获取对象指定的annotation注解,如果有,返回对应的对象,否则返回null。

5.4.3 getAnnotations()方法

         获取对象所有的annotation注解,返回一个Annotation类型的数组。

5.4.4 getParameterAnnotation()方法

        获取构造方法Constructor类和方法Method类中注解的特用方法,用来获得方法的参数添加的注解,以Annotation类型的数组返回,数组中的顺序与声明的顺序相同。

        如果该方法没有参数,则返回一个长度为0的数组;如果存在未添加Annotation注解的参数,则用一个长度为0的嵌套数组占位。

Constructor_Annotation.java:
/*** 定义一个注释构造方法的注解**/
package reflectdemo;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)     //指定运行时加载到JVM中
@Target(ElementType.CONSTRUCTOR)        //指定适用元素为构造方法
public @interface Constructor_Annotation {String value() default "默认构造方法";    //定义一个具有默认值的String类型成员value
}
Field_Method_Parameter_Annotation.java:
/*** 定义一个适用于字段、方法、参数的注解*/
package reflectdemo;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)     //运行时加载到jvm
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})   //适用于Field,Method,Parameter
public @interface Field_Method_Parameter_Annotation {String describe();      //没有默认值的String成员describeClass type() default void.class;    //有默认值的Class类型成员type
}
Record.java:
package reflectdemo;public class Record {@Field_Method_Parameter_Annotation(describe = "编号", type = int.class)    //注释字段int id;@Field_Method_Parameter_Annotation(describe = "姓名", type = String.class)String name;@Constructor_Annotation()       //默认值构造方法public Record() {}@Constructor_Annotation("有立即初始化参数的构造方法~")public Record(@Field_Method_Parameter_Annotation(describe = "编号", type = int.class) int id,@Field_Method_Parameter_Annotation(describe = "姓名", type = String.class) String name) {this.id = id;this.name = name;}@Field_Method_Parameter_Annotation(describe = "获得编号的方法", type = int.class)public int getId() {return id;}@Field_Method_Parameter_Annotation(describe = "设置编号的方法")public void setId(@Field_Method_Parameter_Annotation(describe = "编号", type = int.class) int id) {this.id = id;}@Field_Method_Parameter_Annotation(describe = "获得姓名的方法", type = String.class)public String getName() {return name;}@Field_Method_Parameter_Annotation(describe = "设置姓名的方法")public void setName(@Field_Method_Parameter_Annotation(describe = "姓名", type = String.class) String name) {this.name = name;}}
反射获取构造方法的注解: 

readAnnoInfo.java:

package reflectdemo;import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;public class readAnnoInfo {public static void main(String[] args) {Record record = new Record();Class recordC = record.getClass();Constructor[] declaredConstructor = recordC.getDeclaredConstructors();  //获取所有构造方法//查看构造方法是否具有指定类型的注释System.out.println("--------构造方法的描述如下----------");for (int c = 0; c < declaredConstructor.length; c++) {Constructor constructor = declaredConstructor[c];if (constructor.isAnnotationPresent(Constructor_Annotation.class)) {//获取指定的Annotation注解Constructor_Annotation ca = (Constructor_Annotation) constructor.getAnnotation(Constructor_Annotation.class);System.out.println("构造方法的注解是:" + ca.value());     //获取注释信息}}}
}输出:--------构造方法的描述如下----------构造方法的注解是:默认构造方法构造方法的注解是:有立即初始化参数的构造方法~
反射获取构造方法的参数的注释:

readAnnoInfo.java:

package reflectdemo;import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;public class readAnnoInfo {public static void main(String[] args) {Record record = new Record();Class recordC = record.getClass();Constructor[] declaredConstructor = recordC.getDeclaredConstructors();  //获取所有构造方法//查看构造方法是否具有指定类型的注释for (int c = 0; c < declaredConstructor.length; c++) {Constructor constructor = declaredConstructor[c];//获取构造方法的参数的注释Annotation[][] param_annotations = constructor.getParameterAnnotations();System.out.println("--------方法的参数描述如下----------");for (int p = 0; p < param_annotations.length; p++) {int length = param_annotations[p].length;if (length == 0) {System.out.println("参数未添加注释~");} elsefor (int j = 0; j < param_annotations[p].length; j++) {//获得参数的注解Field_Method_Parameter_Annotation param_inno = (Field_Method_Parameter_Annotation) param_annotations[p][j];System.out.print("    "+ param_inno.describe());      //获得参数的描述System.out.println("    "+ param_inno.type());          //获取参数的类型}}}}
}输出:--------方法的参数描述如下----------编号    int 姓名    class java.lang.String
反射获取字段的注释:

readAnnoInfo.java:

package reflectdemo;import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;public class readAnnoInfo {public static void main(String[] args) {Record record = new Record();Class recordC = record.getClass();//获取字段的注释信息Field[] myDeclaredFields = recordC.getDeclaredFields();System.out.println("--------字段描述如下----------");for (int f = 0; f < myDeclaredFields.length; f++) {Field myField = myDeclaredFields[f];//判断是否有指定的注释类型if (myField.isAnnotationPresent(Field_Method_Parameter_Annotation.class)) {//获得指定类型的注释Field_Method_Parameter_Annotation fa = myField.getAnnotation(Field_Method_Parameter_Annotation.class);System.out.print("    " + fa.describe());System.out.println("    " + fa.type());}}}
}输出:
--------字段描述如下----------编号    int姓名    class java.lang.String
反射获取参方法的注解+方法包含参数的注解

readAnnoInfo.java:

package reflectdemo;import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class readAnnoInfo {public static void main(String[] args) {Record record = new Record();Class recordC = record.getClass();//获取方法及其参数的注释信息Method[] myMethods = recordC.getDeclaredMethods();System.out.println("--------自定义方法注解描述如下----------");for (int m = 0; m < myMethods.length; m++) {Method method = myMethods[m];if (method.isAnnotationPresent(Field_Method_Parameter_Annotation.class)) {Field_Method_Parameter_Annotation method_anno = method.getAnnotation(Field_Method_Parameter_Annotation.class);System.out.print("    " + method_anno.describe());       //获取方法的描述System.out.println("    " + method_anno.type());         //获取方法的类型//获取该方法的参数的注释Annotation[][] param_annotations = method.getParameterAnnotations();System.out.println("=======自定义方法的参数注解描述如下=======");for (int p = 0; p < param_annotations.length; p++) {int length = param_annotations[p].length;if (length == 0) {System.out.println("自定义方法的参数没有添加Annotation注释信息");} elsefor (int j = 0; j < length; j++) {//获取指定类型注释Field_Method_Parameter_Annotation param_anno = (Field_Method_Parameter_Annotation) param_annotations[p][j];System.out.print("    " + param_anno.describe());System.out.println("    " + param_anno.type());}}}System.out.println();}}
}输出:--------自定义方法注解描述如下----------获得姓名的方法    class java.lang.String=======自定义方法的参数注解描述如下=======设置姓名的方法    void=======自定义方法的参数注解描述如下=======姓名    class java.lang.String获得编号的方法    int=======自定义方法的参数注解描述如下=======设置编号的方法    void=======自定义方法的参数注解描述如下=======编号    int
反射readAnnoInfo.java文件整体:
package reflectdemo;import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class readAnnoInfo {public static void main(String[] args) {Record record = new Record();Class recordC = record.getClass();Constructor[] declaredConstructor = recordC.getDeclaredConstructors();  //获取所有构造方法
//        查看构造方法是否具有指定类型的注释System.out.println("--------构造方法的描述如下----------");for (int c = 0; c < declaredConstructor.length; c++) {Constructor constructor = declaredConstructor[c];if (constructor.isAnnotationPresent(Constructor_Annotation.class)) {//获取指定的Annotation注解Constructor_Annotation ca = (Constructor_Annotation) constructor.getAnnotation(Constructor_Annotation.class);System.out.println("构造方法的注解是:" + ca.value());       //获取注释信息}//获取构造方法的参数的注释Annotation[][] param_annotations = constructor.getParameterAnnotations();System.out.println("--------方法的参数描述如下----------");for (int p = 0; p < param_annotations.length; p++) {int length = param_annotations[p].length;if (length == 0) {System.out.println("参数未添加注释~");} elsefor (int j = 0; j < param_annotations[p].length; j++) {//获得参数的注解Field_Method_Parameter_Annotation param_inno = (Field_Method_Parameter_Annotation) param_annotations[p][j];System.out.print("    " + param_inno.describe());      //获得参数的描述System.out.println("    " + param_inno.type());          //获取参数的类型}}}//获取字段的注释信息Field[] myDeclaredFields = recordC.getDeclaredFields();System.out.println("--------字段描述如下----------");for (int f = 0; f < myDeclaredFields.length; f++) {Field myField = myDeclaredFields[f];//判断是否有指定的注释类型if (myField.isAnnotationPresent(Field_Method_Parameter_Annotation.class)) {//获得指定类型的注释Field_Method_Parameter_Annotation fa = myField.getAnnotation(Field_Method_Parameter_Annotation.class);System.out.print("    " + fa.describe());System.out.println("    " + fa.type());}}//获取方法及其参数的注释信息Method[] myMethods = recordC.getDeclaredMethods();System.out.println("--------自定义方法注解描述如下----------");for (int m = 0; m < myMethods.length; m++) {Method method = myMethods[m];if (method.isAnnotationPresent(Field_Method_Parameter_Annotation.class)) {Field_Method_Parameter_Annotation method_anno = method.getAnnotation(Field_Method_Parameter_Annotation.class);System.out.print("    " + method_anno.describe());       //获取方法的描述System.out.println("    " + method_anno.type());         //获取方法的类型//获取该方法的参数的注释Annotation[][] param_annotations = method.getParameterAnnotations();System.out.println("=======自定义方法的参数注解描述如下=======");for (int p = 0; p < param_annotations.length; p++) {int length = param_annotations[p].length;if (length == 0) {System.out.println("自定义方法的参数没有添加Annotation注释信息");} elsefor (int j = 0; j < length; j++) {//获取指定类型注释Field_Method_Parameter_Annotation param_anno = (Field_Method_Parameter_Annotation) param_annotations[p][j];System.out.print("    " + param_anno.describe());System.out.println("    " + param_anno.type());}}}System.out.println();}}
}输出:--------构造方法的描述如下----------构造方法的注解是:默认构造方法--------方法的参数描述如下----------构造方法的注解是:有立即初始化参数的构造方法~--------方法的参数描述如下----------编号    int姓名    class java.lang.String--------字段描述如下----------编号    int姓名    class java.lang.String--------自定义方法注解描述如下----------获得姓名的方法    class java.lang.String=======自定义方法的参数注解描述如下=======设置姓名的方法    void=======自定义方法的参数注解描述如下=======姓名    class java.lang.String获得编号的方法    int=======自定义方法的参数注解描述如下=======设置编号的方法    void=======自定义方法的参数注解描述如下=======编号    int

查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"Java--Class类与反射+Annotation注解":http://eshow365.cn/6-28330-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!