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

时间:2013-06-06 08:19:30

标签: java methods parameters

已经有几个月的时间了,我非常赞成Python。现在我回到java来预测约束。 现在,我想知道是否有办法在函数本身内以编程方式获取函数的所有参数(带值)。

类似这样的事情

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

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

其中getpars()应返回HashMap name,value对。

所以从示例中应该是

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

有这样的东西吗?

6 个答案:

答案 0 :(得分:2)

您无法获取参数的名称,因为它只是名称的价值。如果您想在Map中使用参数名称,请定义一个与您的参数名称匹配的字符串并将其放入。

阅读this类似问题。接受的答案似乎是使用第三方库的解决方案。

答案 1 :(得分:1)

不幸的是,这是不可能的。您唯一能做的就是使用reflection检索特定方法的参数类型列表。

但无法使用name - >获取地图每个参数的value都传递给方法本身。

答案 2 :(得分:1)

您无法动态获取参数的名称,也无法以除使用变量名称之外的任何方式查找值。然而,JAVA有下一个最好的东西:变量参数。如果您想拥有动态数量的参数,可以按如下方式声明方法:

public void foo(Object... args)

当您调用该方法时,您将使用任意数量的参数调用它; foo(1, 2, "ABC")foo(new File("config.dat"), new Scanner(), 88.5D)都是有效的通话。在函数内部,args将是一个包含所有参数的数组。

只是一些使用技巧。一般而言,上述方法声明不被视为良好形式。通常,您可以更加具体。仔细考虑是否需要所有这些灵活性,并考虑使用一些重载方法或可能将HashMap传递给函数。实际上,你很少需要在广泛的意义上拥有动态参数。

答案 3 :(得分:1)

您可以使用:

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

或使用地图制作工具,请参阅builder-for-hashmap

答案 4 :(得分:0)

Noramlly你不能。但是如果你使用反射,请参阅API类Method

参见方法getTypeParameters()

  

返回TypeVariable对象的数组,这些对象表示由此GenericDeclaration对象以声明顺序表示的泛型声明声明的类型变量。如果底层泛型声明未声明类型变量,则返回长度为0的数组。   你可以得到

答案 5 :(得分:0)

有一些hacky方法来获取被调用方法的参数值(但你必须明白参数是未命名的,你能做的最好就是得到arg0 .... argN)。

  1. 使用代理
  2. 面向方面编程(AspectJ,Spring AOP)
  3. 让我们考虑第一种方法。假设我们想在执行某些接口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);
        }
    }