Class类与java反射

1、介绍

通过java反射机制,实现访问、检测和修改描述Java对象本身信息的功能。java反射机制的功能十分强大,在java.lang.reflect包中提供了对该功能的支持。

2、反射可访问的主要描述信息

利用Class类的对象textFieldC,可以访问用来返回该对象的textField对象的描述信息。

Class textFieldC=textField.getClass();//textField为JTextField类的对象
通过反射可访问的主要描述信息
组成部分 访问方法 返回值类型 说明

包路径

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的构造方法
getMethods(String name,Class... parameterTypes) Method对象 获得权限为public的指定方法
getDeclaredMethods() Method型数组 获得所有方法,按声明顺序返回
getDeclaredMethods(String name,Class... parameterTypes)) Method对象 获得指定方法
成员变量 getFields() Field型数组 获得所有权限为public的成员变量
getFields(String name) Field对象 获得权限为public的指定成员变量
getDeclaredFields() Field型数组 获得所有成员变量,按声明顺序返回
getDeclaredField(String name) Field对象 获得指定成员变量
内部类 getClasses() Class型数组 获得所有权限为public的内部类
getDeclaredClasses() Class型数组 获得所有内部类
内部类的声明类 getDeclaringClass() Class对象 如果该类为内部类,则返回它的成员类,否则返回null

3、访问构造方法

在通过下一列组方法访问构造方法时,将返回Constructor类型的对象或数组。每个Constructor对象代表一个构造方法。

Constructor类的常用方法
方法 说明
isVarArgs() 查看该构造方法是否允许带有可变数量的参数,如果允许则返回true,否则返回false
getParameterTypes() 按照声明顺序以Class数组的形式获得该构造方法的各个参数的类型
getExceptionTypes() 以Class数组的形式获得该构造方法可能抛出的异常类型
newInstance(Object...initargs) 通过该构造方法利用指定参数创建一个该类的对象,如果未设置参数则表示采用默认无参数的构造方法
setAccessible(boolean flag) 如果该构造方法的权限为private,默认为不允许通过反射利用newInstance(Object...initargs)方法创建对象。如果先执行该方法,并将入口参数设为true,则允许创建
getModifiers() 获得可以解析出该构造方法所采用修饰符的整数

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

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

eg:判断对象constructor所代表的构造方法是否被private修饰,以及以字符串形式获得构造方法的所有修饰符的代码如下:

int modifiers=constructor.getModifiers();
boolean isEmbelishByPrivate=Modifier.isPrivate(modifiers);
String embellishment=Modifier.toString(modifiers);

4、访问构造方法代码


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) throws NumberFormatException{
        if(0import java.lang.reflect.Constructor;

/**
 * 主类,用于通过反射机制演示如何访问和操作Example_01类的构造方法。
 */
public class Main_01 {
    public static void main(String[] args) {
        // 创建Example_01类的一个实例,假设它有一个接受三个字符串参数的构造方法。
        Example_01 example = new Example_01("10", "20", "30");
        // 获取example对象的运行时类。
        Class exampleC = example.getClass();
        // 获取该类声明的所有构造方法。
        Constructor[] declaredConstructors = exampleC.getDeclaredConstructors();
        // 遍历所有构造方法。
        for (int i = 0; i < declaredConstructors.length; i++) {
            Constructor constructor = declaredConstructors[i];
            // 打印该构造方法是否接受可变数量的参数。
            System.out.println("查看是否允许带有可变数量的参数:" + constructor.isVarArgs());
            // 打印该构造方法的入口参数类型。
            System.out.println("该构造方法的入口参数类型依次为:");
            Class[] parameterTypes = constructor.getParameterTypes(); // 获取所有参数的类型
            for (int j = 0; j < parameterTypes.length; j++) {
                System.out.println("" + parameterTypes[j]);
            }
            // 打印该构造方法可能抛出的异常类型。
            System.out.println("该构造方法可能抛出的异常类型为:");
            // 获得所有可能抛出的异常信息类型
            Class[] exceptionType = constructor.getExceptionTypes();
            // 注意:这里有一个错误,应该使用j而不是i来遍历exceptionType数组。
            for (int j = 0; j < exceptionType.length; j++) {
                System.out.println("" + exceptionType[j]); // 修正为exceptionType[j]
            }
            Example_01 example2 = null;
            // 尝试使用不同的参数调用构造方法来创建新的Example_01实例。
            while (example2 == null) {
                try {
                    // 根据构造方法的索引选择不同的调用方式。
                    if (i == 2) {
                        // 假设第三个构造方法是无参构造方法。
                        example2 = (Example_01) constructor.newInstance();
                    } else if (i == 1) {
                        // 假设第二个构造方法是接受一个字符串和一个整数的构造方法。
                        // 注意:这里有一个错误,因为Example_01类的构造方法可能不接受这样的参数。
                        example2 = (Example_01) constructor.newInstance("7", 5);
                    } else {
                        // 对于其他构造方法,尝试传递一个字符串数组作为参数。
                        // 注意:这里假设构造方法接受一个Object数组,这在大多数情况下是不正确的。
                        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); // 设置为允许访问私有构造方法
                }
            }
            // 如果成功创建了Example_01实例,则调用其print方法并打印换行符。
            if (example2 != null) {
                example2.print();
                System.out.println();
            }
        }
    }
}

5、程序运行结果

Class类与java反射_第1张图片Class类与java反射_第2张图片

你可能感兴趣的:(java,开发语言)