java—以编程方式检索方法的参数和值

e3bfsja2  于 2021-06-30  发布在  Java
关注(0)|答案(5)|浏览(340)

几个月以来,我一直非常支持python。现在我要回到java来处理项目约束。现在,我想知道是否有一种方法可以在函数本身中以编程方式获取函数的所有参数(带值)。
像这样的

public void foo(String arg1,String arg2, Integer arg3){
... pars = ...getpars();  
}

foo("abc","dfg",123);

哪里 getpars() 应该返回一个 HashMapname,value 对。
所以从这个例子来看

arg1,"abc"
arg2,"dfg"
arg3,123

有这样的事吗?

eaf3rand

eaf3rand1#

获取被调用方法的参数值的方法有很多种(但是您必须了解参数是未命名的,最好的方法是获取arg0。。。。argn)。
使用代理
面向方面编程(aspectj、spring aop)
让我们考虑第一种方法。假设我们想在执行某个接口methodparamsinterface的方法之前记录参数,给你。如果您想在逻辑中使用这些参数,请考虑在invocationhandler中实现它们(或者改用easymock)

interface MethodParamsInterface {
    void simpleMethod(int parm1, int parm2);
    void simpleMethod(int parm1, int parm2, int param3);
}

public class MethodParams implements MethodParamsInterface {
    public void simpleMethod(int parm1, int parm2) {
        //business logic to be put there
    }

    public void simpleMethod(int parm1, int parm2, int param3) {
        //business logic to be put there
    }

    public MethodParamsInterface wrappedInstance() throws Exception {
        Class<?> proxyClass = Proxy.getProxyClass(MethodParams.class.getClassLoader(), MethodParamsInterface.class);
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Map<String, Object> params = new LinkedHashMap<String, Object>(args.length);
                for (int i = 0; i < args.length; i++)
                    params.put("arg" + i, args[i]);

                //printing out the parameters:
                for (Map.Entry<String, Object> paramValue : params.entrySet()) {
                    System.out.println(paramValue.getKey() + " : " + paramValue.getValue());
                }

                return MethodParams.this.getClass().getMethod(method.getName(), method.getParameterTypes()).invoke(MethodParams.this, args);
            }
        };
        return (MethodParamsInterface) proxyClass.getConstructor(new Class[]{InvocationHandler.class}).newInstance(invocationHandler);
    }

    public static void main(String[] args) throws Exception {
        MethodParams instance = new MethodParams();
        MethodParamsInterface wrapped = instance.wrappedInstance();

        System.out.println("First method call: ");

        wrapped.simpleMethod(10, 20);

        System.out.println("Another method call: ");

        wrapped.simpleMethod(10, 20, 30);
    }
}
5gfr0r5j

5gfr0r5j2#

您可以使用:

void foo(String... args) {
    for (String arg: args) { }
    for (int i = 0; i < args.length - 1; i += 2) {
        map.put(args[i], args[i + 1];
    }
}

foo("a", "1", "b", "2");

或者使用Map生成器,请参见hashmap的生成器。

rhfm7lfc

rhfm7lfc3#

您不能动态地获得参数的名称,也不能用变量名以外的任何方式找到值。然而,java还有第二个优点:变量参数。如果希望参数数量动态变化,可以按如下方式声明方法:

public void foo(Object... args)

当你调用这个方法时,你可以用任意数量的参数来调用它; foo(1, 2, "ABC") 以及 foo(new File("config.dat"), new Scanner(), 88.5D) 都是有效呼叫。在函数内部, args 将是一个按顺序包含所有参数的数组。
不过,这只是一些使用技巧。一般来说,上面的方法声明不被认为是好的形式。通常,你可以更具体。仔细考虑是否需要所有这些灵活性,并考虑使用一些重载方法或可能传递 HashMap 改为函数。从广义上讲,很少需要动态参数。

fnvucqvd

fnvucqvd4#

不幸的是,这是不可能的。您唯一能做的就是使用 reflection .
但是没有办法得到一张Map name -> value 传递给方法本身的每个参数的。

cwtwac6a

cwtwac6a5#

您无法获取参数的名称,因为它不是值,只是一个名称。如果你想让你的Map中的参数名定义一个字符串匹配你的参数名并把它放进去。
读这个类似的问题。公认的答案似乎有一个使用第三方库的解决方案。

相关问题