反射Class.forName和ClassLoader区别与属性和方法的调用

package test;
/**
 * @Author xu
 * @create 2023/7/14 11
 */
public class ClassForName {
    
    

    //静态代码块
    static {
    
    
        System.out.println("执行了静态代码块");
    }
    //静态变量
    private static String staticFiled = staticMethod();

    private static String staticFiled2="2";

    private static String staticFiled3="3";

    //赋值静态变量的静态方法
    public static String staticMethod(){
    
    
        System.out.println("执行了静态方法");
        return "给静态字段赋值了";
    }

    public  String method(String dd){
    
    
        System.out.println("00");
        return dd;
    }
}

1:使用Class.forName()的测试方法,会对ClassForName 进行初始化:

public static void main(String[] args) {
    
    
        try {
    
    
            Class<?> aClass = Class.forName("test.ClassForName");
            //获取属性数组
            Field[] declaredFields = aClass.getDeclaredFields();
            for (int i = 0; i < declaredFields.length; i++) {
    
    
            	//如果属性为private需要设置setAccessible为true才能访问
                declaredFields[i].setAccessible(true);
                String aa = (String) declaredFields[i].get(aClass);
            }
            //对指定方法名进行操作
            Method method2 = aClass.getDeclaredMethod("method", String.class);
            //如果方法为private需要设置setAccessible为true才能访问
            method2.setAccessible(true);
            Object instance2 = aClass.newInstance(); // 创建类的实例
            Object result = method2.invoke(instance2, "参数1"); // 调用方法并获取返回值
            System.out.println("====:"+result);
            System.out.println("#########-------------结束符------------##########");
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
        }

    }

要获取 Class.forName 加载的类中的全部方法并进行调用,且每个方法的参数不一致,按照以下步骤进行操作

首先,确保已经正确加载了目标类,可以使用 Class.forName 方法来加载类

Class<?> aClass = Class.forName("org.jeecg.modules.system.service.impl.ClassForName");

使用 getDeclaredMethods 方法获取类中声明的所有方法。这将返回一个 Method 对象数组

Method[] methods = aClass.getDeclaredMethods();

遍历 methods 数组,对每个方法进行操作。您可以通过 Method 对象来获取方法的名称、参数类型和返回类型等信息

for (Method method : methods) {
    
    
    String methodName = method.getName(); // 获取方法名称
    Class<?>[] parameterTypes = method.getParameterTypes(); // 获取参数类型数组
    Class<?> returnType = method.getReturnType(); // 获取返回类型

    System.out.println("Method Name: " + methodName);
    System.out.println("Return Type: " + returnType);
    System.out.println("Parameter Types: " + Arrays.toString(parameterTypes));

    // 动态调用方法
    method.setAccessible(true); // 设置方法可访问性

    // 准备方法的参数
    Object[] arguments = new Object[parameterTypes.length];
    for (int i = 0; i < parameterTypes.length; i++) {
    
    
        Class<?> parameterType = parameterTypes[i];
        // 根据参数类型创建对应的参数值
        // 这里根据您的实际需求来创建不同的参数值
        // 示例代码中使用了默认的参数值
        if (parameterType == String.class) {
    
    
            arguments[i] = "参数字符串";
        } else if (parameterType == int.class) {
    
    
            arguments[i] = 123;
        }
        // 其他参数类型的处理...
    }

    // 调用方法并获取返回值
    Object result = method.invoke(aClass.newInstance(), arguments); // 注意这里使用了 aClass 的实例来调用方法

    System.out.println("Method Invocation Result: " + result);
}

2:使用ClassLoader的测试方法,不会对ClassForName 进行初始化:

public static void main(String[] args) {
    
    
        try {
    
    
            Class<?> aClass = ClassLoader.getSystemClassLoader().loadClass("test.ClassForName");
            Field[] declaredFields = aClass.getDeclaredFields();
            for (int i = 0; i < declaredFields.length; i++) {
    
    
                declaredFields[i].setAccessible(true);
                String aa = (String) declaredFields[i].get(aClass);
            }
            System.out.println("#########-------------结束符------------##########");
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
        }

    }

猜你喜欢

转载自blog.csdn.net/qq_19891197/article/details/131720363