日拱一卒:Java 反射之动态调用方法

2023-09-21  本文已影响0人  Tinyspot

1. 获取方法

/**
 * all the public methods
 * including inherited from superclasses and superinterfaces.
 */
Method[] methods = clazz.getMethods();
/**
 * all the declared methods, including public, protected, default (package) access, and private methods, 
 * but excluding inherited methods.
 */
Method[] declaredMethods = clazz.getDeclaredMethods();

1.1 打印方法信息

@Test
public void reflection() throws ClassNotFoundException {
    // Class<?> clazz = GreetService.class;
    Class<?> clazz = Class.forName("com.example.concrete.starter.service.GreetService");
    Method[] methods = clazz.getMethods();
    for (Method method : methods) {
        System.out.println(method.toString());
    }
}

打印信息

public abstract java.lang.String com.example.concrete.starter.service.GreetService.greeting(com.example.concrete.common.domain.UserDTO,java.lang.String)
public abstract java.lang.String com.example.concrete.starter.service.GreetService.greet(java.lang.String,java.lang.String)
public abstract java.lang.String com.example.concrete.starter.service.GreetService.greet(java.lang.String)
public abstract java.lang.String com.example.concrete.starter.service.GreetService.greet()

2. 反射调用方法

@Service
public class GreetServiceImpl implements GreetService {
    @Override
    public String greeting(UserDTO userDTO, String env) {
        return "greeting run..." + JSON.toJSONString(userDTO) + "; " + env;
    }

    @Override
    public String greet() {
        return "greet...";
    }

    @Override
    public String greet(Integer value) {
        return "Integer:" + value;
    }

    @Override
    public String greet(String name) {
        return "Hello " + name;
    }

    @Override
    public String greet(String name, String myName) {
        return "Hello " + name + ", my name is " + myName;
    }
}

2.1 动态方法调用

/**
 * 1. 获取类的 Class 对象
 * 2. 获取 Method 对象:clazz.getMethods()
 * 3. method.invoke(Object obj, Object... args)
 *      - obj 实例对象
 *      - args 参数值
 * 4. 获取实例对象:clazz.newInstance()
 */
@Test
public void invoke() throws Exception {
    Object result = null;

    // Class<?> clazz = GreetServiceImpl.class;
    Class<?> clazz = Class.forName("com.example.concrete.starter.service.impl.GreetServiceImpl");
    Method[] methods = clazz.getMethods();
    for (Method method : methods) {
        if (method.toString().equals("public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet()")) {
            result = method.invoke(clazz.newInstance());
            System.out.println(result);
        } else if (method.toString().equals("public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(java.lang.String)")) {
            result = method.invoke(clazz.newInstance(), "xing");
            System.out.println(result);
        } else if (method.toString().equals("public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(java.lang.String,java.lang.String)")) {
            result = method.invoke(clazz.newInstance(), "Alice", "xing");
            System.out.println(result);
        } else if (method.toString().equals("public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greeting(com.example.concrete.common.domain.UserDTO,java.lang.String)")) {
            result = method.invoke(clazz.newInstance(), new UserDTO("xing", 20), "Local");
            System.out.println(result);
        }
    }
}

2.2 动态参数组装

@Test
public void invoke() throws Exception {
    Class<?> clazz = Class.forName("com.example.concrete.starter.service.impl.GreetServiceImpl");

    Object result = invokeMethod(clazz, "public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet()", new ArrayList<>());
    Object result1 = invokeMethod(clazz, "public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(java.lang.Integer)", Arrays.asList("1001"));
    Object result2 = invokeMethod(clazz, "public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(java.lang.String)", Arrays.asList("xing"));
    Object result3 = invokeMethod(clazz, "public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(java.lang.String,java.lang.String)", Arrays.asList("Alice", "xing"));
    Object result4 = invokeMethod(clazz, "public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl" +
            ".greeting(com.example.concrete.common.domain.UserDTO,java.lang.String)", Arrays.asList("{\"age\":20,\"name\":\"xing\"}", "Local"));
    System.out.println(result4);
}

方法调用

private Object invokeMethod(Class<?> clazz, String methodSign, List<String> arguments) throws Exception {
    Method[] methods = clazz.getMethods();
    for (Method method : methods) {
        // 实例对象
        Object instance = clazz.newInstance();
        Class<?>[] parameterTypes = method.getParameterTypes();
        // System.out.println(method.toString());

        if (method.toString().equals(methodSign)) {
            return method.invoke(instance, assemblyArgs(arguments, parameterTypes));
        }
    }
    return null;
}
/**
 * 参数组装
 * @param arguments 参数值
 * @param parameterTypes 参数类型
 * @return
 */
private Object[] assemblyArgs(List<String> arguments, Class<?>[] parameterTypes) {
    List<Object> args = new ArrayList<>();

    for (int i = 0; i < arguments.size(); i++) {
        args.add(getArgValue(parameterTypes[i], arguments.get(i)));
    }
    return args.toArray();
}
private static Object getArgValue(Class<?> parameterType, String arg) {
    if (StringUtils.isBlank(arg)) {
        return null;
    }
    arg = StringUtils.trim(arg);

    if (parameterType.equals(String.class)) {
        return arg;
    }

    if (parameterType.equals(Integer.class)) {
        return Integer.valueOf(arg);
    }

    if (parameterType.equals(Date.class)) {
        if (arg.length() == 10) {
            // 例如:2023-01-01
            arg += " 00:00:00";
        }
        return DateUtil.parseToDateTime(arg);
    }

    // 转为对象
    return JSON.parseObject(arg, parameterType);
}
上一篇 下一篇

猜你喜欢

热点阅读