使用反射调用方法/将列表转换为 Var Args

发布于 2024-11-15 16:56:45 字数 636 浏览 3 评论 0原文

我有一个参数列表和方法名称。我想使用反射调用该方法。 当我检查 Method.invoke 的 java 文档时,它就像 Method.invoke(object o, Object args...) 。 我知道第一个参数要传递什么(即,如果实例方法是调用哪个方法的实例),args 是该方法的参数。

但现在我有了包含要传递给该方法的值的列表。

举例来说:我想调用方法 ClassName.methodName(String , int, int) 并且我有一个包含 {val1, 3, 4} 的列表。

使用反射,它可能类似于 Method.invoke(classNameInstance, ??????)。但我不确定如何将参数列表转换为可变参数并传递。

一种方法可能是,如果我知道列表大小为 3,那么我可以编写 Method.invoke (classNameInstance, list.get(0), list.get(1), list.get(2))。

但我想要动态调用的一些方法需要 0 到 12 个参数。所以创建 switch case 并编写 12 个 case 看起来并不“好”。每个将检查参数的数量并使用参数构建单独的调用。

除了使用 switch case 之外,还有什么方法可以解决这个问题吗?

任何帮助将不胜感激。

I have a list of parameters and I have the method name. I want to invoke the method using reflection.
When I checked the java doc for Method.invoke its like Method.invoke(object o, Object args...) .
I know what to pass for the first paramter (i.e instance on which method to be invoked if its instance method) and args is the parameters for the method.

But now I have have the list which contains values which are to be passed to the method.

Say for example: I want to invoke method ClassName.methodName(String , int, int) and I have a List which contains {val1, 3, 4}.

Using reflection it may be like Method.invoke (classNameInstance, ??????). But I am not sure how to convert a list of arguments to varargs and pass.

One way may be If i know that list size is 3 then I may write Method.invoke (classNameInstance, list.get(0), list.get(1), list.get(2)).

But some of the methods which I want to dynamically invoke take 0 to 12 arguments. So it doesn't look "good" to create switch case and write 12 cases. Each will check with number of parameters and build the separate call with parameters.

Any way to go about this except from using switch case?

Any help will be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怪我闹别瞎闹 2024-11-22 16:56:45

符号 Object... 只不过是 Object[]。它只是数组符号的语法糖。传递一个数组,它就会起作用。

The Notation Object... means nothing more than Object[]. It is just syntactic sugar for an Arraynotation. Pass an Array and it will work.

梦途 2024-11-22 16:56:45

编辑:这是一种更通用的方法,适用于任何类型的可变参数:

        Class<?> c = int.class;
        Object array = Array.newInstance(c, list.size());
        for (int i = 0; i < list.size(); i++)
                Array.set(array, i, list.get(i));
        Test.class.getDeclaredMethod("test", array.getClass()).invoke(
                new Test(), new Object[] { array });

void m(X...p)void m 具有相同的签名(X[] p)。您不能在同一个类中声明两者。

以下是如何使用反射(基元和非基元)调用它们:

import java.util.*;
import java.lang.reflect.*;

class Test
{
        public static void main(String[] args) throws Exception
        {
                List<Integer> list = new ArrayList<Integer>();
                list.add(1); list.add(2); list.add(3);
                Test.class.getDeclaredMethod("test", Integer[].class).invoke(
                    new Test(), new Object[] { list.toArray(new Integer[0]) });
                int[] params = new int[list.size()];
                for (int i = 0; i < params.length; i++) params[i] = list.get(i);
                Test.class.getDeclaredMethod("test", int[].class).invoke(
                    new Test(), new Object[] { params });
        }

        public void test(int ... i) { System.out.println("int[]: " + i[0] + ", " + i[1] + ", " + i[2]); }
        public void test(Integer... i) { System.out.println("Integer[]" + Arrays.asList(i)); }
}

EDITED: this is a more general approach that works for any type of vararg params:

        Class<?> c = int.class;
        Object array = Array.newInstance(c, list.size());
        for (int i = 0; i < list.size(); i++)
                Array.set(array, i, list.get(i));
        Test.class.getDeclaredMethod("test", array.getClass()).invoke(
                new Test(), new Object[] { array });

void m(X...p) has the same signature as void m(X[] p). You cannot declare both in the same class.

Here is how to invoke them using reflection (primitives and non-primitives):

import java.util.*;
import java.lang.reflect.*;

class Test
{
        public static void main(String[] args) throws Exception
        {
                List<Integer> list = new ArrayList<Integer>();
                list.add(1); list.add(2); list.add(3);
                Test.class.getDeclaredMethod("test", Integer[].class).invoke(
                    new Test(), new Object[] { list.toArray(new Integer[0]) });
                int[] params = new int[list.size()];
                for (int i = 0; i < params.length; i++) params[i] = list.get(i);
                Test.class.getDeclaredMethod("test", int[].class).invoke(
                    new Test(), new Object[] { params });
        }

        public void test(int ... i) { System.out.println("int[]: " + i[0] + ", " + i[1] + ", " + i[2]); }
        public void test(Integer... i) { System.out.println("Integer[]" + Arrays.asList(i)); }
}
半枫 2024-11-22 16:56:45

Varargs 实际上只是一个数组。

该方法可以像这样检索,假设它采用 int... args:

Method method = MyClass.class.getMethod("someMethod", int[].class);
method.invoke(myInstance, argumentsList.toArray());

Varargs is really just an array.

The method can be retrieved like this, assuming it takes int... args:

Method method = MyClass.class.getMethod("someMethod", int[].class);
method.invoke(myInstance, argumentsList.toArray());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文