Java reflect 动态调用静态方法

本文档展示了如何使用Java反射创建单例对象,并提供了SpringBoot的ReflectionUtils工具类进行字段和方法操作的示例。通过这些工具,可以方便地在运行时动态访问和修改对象的属性及调用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景说明:

       外围系统想推送账务类数据到中台系统,账务类数据大多数数据都是相似的,少部分差异。所以想只做一个公用接口,根据来源区分,不同的来源调用存储在表里面静态方法做映射或校验。下面是网上找到的一个DEMO。测试时OK的。朋友后面推荐Spring Boot org.springframework.util.ReflectionUtils 实现更方便。此文档记录仅作参考,如果错误或改进意见请各位指正。

测试reflect函数

import java.lang.reflect.*;

public class MyTestClass{
    private static Object pLock = new Object();

    private static MyTestClass p_instance = null;
    private String s_configName = "";
    private boolean b_isFromResource = true;

    public static Object getInstance(String sConfigName,
                                     Boolean bIsFromResource){
        synchronized(pLock){
            if(null == p_instance){
                p_instance =
                        new MyTestClass(sConfigName,bIsFromResource);
            }
            System.out.println("sConfigName = " + sConfigName);
            System.out.println("bIsFromResource = " + bIsFromResource);
        }
        return p_instance;
    }

    private MyTestClass(String sConfigName,Boolean bIsFromResource){
        s_configName = sConfigName;
        b_isFromResource = bIsFromResource.booleanValue();
    }

    public void echoInfo(){
        System.out.println("current arguments : configName=["+
                s_configName+"],isFromResource=["+
                b_isFromResource+"]");
    }

    public static void main(String[] args) throws Exception{
        // 设置方法的传入参数的类型.
        Class[] parameterTypes = new Class[]{
                java.lang.String.class,
                java.lang.Boolean.class
        };


        Method mGetInstance = null;
        String className = "com.netease.dms.MyTestClass";

        Class curTestClass = Class.forName(className);
        try{
            mGetInstance = curTestClass.
                    getMethod("getInstance",parameterTypes);
        }
        catch(NoSuchMethodException e){
            e.printStackTrace();
            mGetInstance = null;
        }

        if(mGetInstance != null){

            Object[] parameter = new Object[2];
            parameter[0] = "src/myconfig.properties";
            parameter[1] = Boolean.FALSE;

            MyTestClass pObj = (MyTestClass)
                    mGetInstance.invoke(
                            null,
                            parameter
                    );

            pObj.echoInfo();
        }
        else{
            throw
                    new Exception("myTest Init Failed from class" +
                            className +
                            System.getProperty("line.seperator","/n") +
                            "method getInstance(String, Boolean) exists.");
        }
    }

测试Spring boot, ReflectionUtils方法

准备一个对象


import com.fasterxml.jackson.annotation.JsonFormat;
import com.netease.core.common.exception.SysException;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;
import java.util.Date;

@Data
public class ReflectionUtilsTestDo {

    public String sourceCode;

    private String batchId = "1234567890";

    @JsonFormat(pattern = "yyyy-MM-dd")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    public Date trxDate;

    private BigDecimal finPeriod;

    public String testMethod(String str, Date date) {
        System.out.println("执行:testMethod");
        return "methodTest1 str = " + str + " date = " + date;
    }

    public String exceptionMethod(String str) {
        throw new SysException("test exception method: " + str);
    }
}

测试方法


import lombok.SneakyThrows;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @author yachao.wu@corp.netease.com
 * @date 2022-05-12
 */
public class ReflectionUtilsTestDemo {

    @SneakyThrows
    public static void main(String[] args) {
        ReflectionUtilsTestDo testDo = new ReflectionUtilsTestDo();
        testDo.setSourceCode("AMS");
        System.out.println("sourceCode = " + testDo.getSourceCode());

        // 获取对象
        Field fieldSource = ReflectionUtils.findField(ReflectionUtilsTestDo.class, "sourceCode");
        System.out.println("对象sourceCode = " + fieldSource);
        System.out.println("对象sourceCode名称 = " + fieldSource.getName());
        System.out.println("对象sourceCode类型 = " + fieldSource.getType());
        System.out.println("对象sourceCode值(只有public对象才可以获取值) = " + ReflectionUtils.getField(fieldSource, testDo));
        // 设置对象值
        ReflectionUtils.setField(fieldSource, testDo, "EBS");
        System.out.println("对象值sourceCode-设置后 = " + ReflectionUtils.getField(fieldSource, testDo));

        // 获取日期类型对象值
        Field fieldTrxDate = ReflectionUtils.findField(ReflectionUtilsTestDo.class, "trxDate");
        System.out.println("对象TrxDate值 = " + ReflectionUtils.getField(fieldTrxDate, testDo));
        ReflectionUtils.setField(fieldTrxDate, testDo, new Date());
        System.out.println("对象TrxDate值-设置后 = " + ReflectionUtils.getField(fieldTrxDate, testDo));

        // 获取注解方法
        Method method = ReflectionUtils.findMethod(ReflectionUtilsTestDo.class, "getSourceCode");
        System.out.println("getSourceCode() =  " + ReflectionUtils.invokeMethod(method, testDo));

        // 获取带参数的方法
        Class[] testMethodClasses = new Class[2];
        testMethodClasses[0] = String.class;
        testMethodClasses[1] = Date.class;
        Method testMethod = ReflectionUtils.findMethod(ReflectionUtilsTestDo.class, "testMethod", testMethodClasses);
        if (testMethod == null) {
            throw new AssertionError("未获取到方法:testMethod");
        }
        Object[] testParameter = new Object[2];
        testParameter[0] = "测试带参数的方法";
        testParameter[1] = new Date();
        System.out.println("testMethod() =  " + ReflectionUtils.invokeMethod(testMethod, testDo, testParameter));

        // 执行带例外的方法
        Class[] exceptionMethodClasses = new Class[1];
        exceptionMethodClasses[0] = String.class;
        Method exceptionMethod = ReflectionUtils.findMethod(ReflectionUtilsTestDo.class, "exceptionMethod", exceptionMethodClasses);
        if (exceptionMethod == null) {
            throw new AssertionError("未获取到方法:exceptionMethod");
        }
        Object[] exceptionParameter = new Object[1];
        exceptionParameter[0] = "测试异常方法";
        try {
            ReflectionUtils.invokeMethod(exceptionMethod, testDo, exceptionParameter);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

控制台日志

sourceCode = AMS
对象sourceCode = public java.lang.String com.netease.dms.ReflectionUtilsTestDo.sourceCode
对象sourceCode名称 = sourceCode
对象sourceCode类型 = class java.lang.String
对象sourceCode值(只有public对象才可以获取值) = AMS
对象值sourceCode-设置后 = EBS
对象TrxDate值 = null
对象TrxDate值-设置后 = Fri Dec 23 11:52:38 CST 2022
getSourceCode() =  EBS
执行:testMethod
testMethod() =  methodTest1 str = 测试带参数的方法 date = Fri Dec 23 11:52:38 CST 2022
test exception method: 测试异常方法

Process finished with exit code 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值