修改java class 文件里面内容 java修改class名称_构造方法

        通过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,反之返回false

getParameterTypes()

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=null
        i=100
        i2=200
        i3=300

        构造方法是:protected reflectdemo.Example_01(java.lang.String,int)
        查看是否允许带有可变数量参数:false
        该构造方法的入口参数类型依次是:
    class java.lang.String
        int
        s=7
        i=5
        i2=0
        i3=0

        构造方法是:private reflectdemo.Example_01()
        查看是否允许带有可变数量参数:false
        该构造方法的入口参数类型依次是:
        在创建对象时抛出异常,下面执行setAccessible()方法:
        s=null
        i=0
        i2=0
        i3=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中的成员变量的值设置为value

getInt(Object obj)

int

获得指定对象obj中类型为int的成员变量的值

setInt(Object obj, int value)

void

将指定对象obj中类型为int的成员变量的值设置为value

getFloat(Object obj)

float

获得指定对象obj中类型为float的成员变量的值

setFloat(Object obj,float value)

void

将指定对象obj中类型为float的成员变量的值设置为value

getBoolean(Object obj)

boolean

获得指定对象obj中类型为boolean的成员变量的值

setBoolean(Object obj, boolean value)

void

将指定对象obj中类型为boolean的成员变量的值设置为value

setAccessible(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,反之返回false

setAccessible(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.String
        int
        获得方法的返回值类型是: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成员describe

    Class 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("参数未添加注释~");
                } else
                    for (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注释信息");
                    } else
                        for (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("参数未添加注释~");
                } else
                    for (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注释信息");
                    } else
                        for (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