美文网首页
日拱一卒:Java 反射之动态调用方法

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

作者: Tinyspot | 来源:发表于2023-09-21 17:45 被阅读0次

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);
}

相关文章

  • Java动态代理

    java动态代理 先看Method反射,调用getDeclaredMethod查找方法;invoke执行方法,返回...

  • Java反射与动态代理

    Java反射 Java反射机制可以动态地获取类的结构,动态地调用对象的方法,是java语言一个动态化的机制 特点:...

  • java反射机制

    java反射机制是为了动态获取类的结构,动态地调用对象的方法 java反射机制 获取类Class对象 A.clas...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • Java系列之 - 反射基础

    java反射 反射:动态获取类的信息,以及动态调用对象的方法的功能。可以理解为动态看透类的能力。 主要功能: 在运...

  • 【日拱一卒】:反射的作用和意义?

    Java的反射:在程序运行过程中,动态的获取类的信息和动态调用对象的方法。反射就是把java类中的各种成分映射成一...

  • Java 反射

    Java反射Java反射API获取Class对象通过反射创建实例对象,调用公共方法通过反射调用私有方法 一.Jav...

  • java 泛型基础(详细例子)

    Java基础之一反射 动态加载类的方法 editPlus配合cmd命令行调用 file-new-java,保存Ja...

  • java反射invoke动态调用方法

    @Autowired标签自动注入TestMapper失败,可能出现的空指针报错: java.lang.NullPo...

  • 有疑问的地方

    反射和动态代理:java动态代理可以在不改变被调用对象源码的前提下,在被调用方法前后增加自己的操作,极大地降低了模...

网友评论

      本文标题:日拱一卒:Java 反射之动态调用方法

      本文链接:https://www.haomeiwen.com/subject/mgczvdtx.html