2013-06-06 72 views
1

已經有好幾個月了,我相當贊成Python。現在我回到java來展示約束條件。 現在,我想知道是否有一種方法可以在函數內部以編程方式獲得函數的所有參數(帶有值)。以編程方式檢索方法的參數和值

像這樣

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

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

其中getpars()應該name,value雙返回HashMap

所以從例子應該是

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

是有這樣的事?

+2

名稱是什麼,在這裏有什麼價值 – PSR

+2

你需要什麼用的? – jlordo

+0

我編輯了問題 – EsseTi

回答

1

不幸的是,這是不可能的。您唯一能做的就是使用reflection來檢索特定方法的參數類型列表。

但是沒有辦法得到一個地圖,其中name - >value傳遞給方法本身。

+0

它實際上可能在Java中使用代理或方面 – Gabriel

2

您無法獲取參數的名稱,因爲它只是一個名稱沒有意義。如果你想讓你的Map中的參數名稱定義一個與你的參數名稱匹配的字符串並將其放入。

閱讀this類似的問題。接受的答案似乎有使用第三方庫的解決方案。

0

Noramlly可以not.But如果使用的是反射,看到API類Method

參見方法getTypeParameters()

返回代表由一般聲明聲明的類型變量的TypeVariable對象的數組由此GenericDeclaration對象表示,按聲明順序。如果基礎泛型聲明聲明沒有類型變量,則返回長度爲0的數組。 你可以得到

1

你不能動態獲取參數的名稱,也不能找到比使用變量名以外的任何方式的值。但是,JAVA擁有第二好的功能:可變參數。如果你想擁有的參數的動態數量,你可以按照如下聲明你的方法:

public void foo(Object... args) 

當你調用該方法,你將與任意數量的參數調用它; foo(1, 2, "ABC")foo(new File("config.dat"), new Scanner(), 88.5D)都是有效的調用。函數內部,args將按順序包含所有參數。

只是一些使用技巧,但。上面的方法聲明通常不被認爲是好的形式。通常,你可以更具體。仔細想想你是否需要所有這些靈活性,並考慮使用一些重載的方法,或者可能將HashMap傳遞給函數。很少有人會真的需要在廣義上具有動態參數。

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

+0

似乎很有趣,在'String'之後'...'的含義是什麼? – EsseTi

+0

@EsseTi它是可變參數。實質上,這與傳遞'String []'作爲參數相同,只是寫得更好。 – fge

0

獲取被調用方法的參數值有一些黑客方法(但您必須明白參數未命名,您可以做的最好的方法是獲取arg0 .... argN)。

  1. 使用代理
  2. 面向方面編程(AspectJ的,春季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); 
    } 
} 
相關問題