2017-09-24 103 views
5

我不確定我在這裏使用的詞彙,如果我錯了,請糾正我。Java傳播運算符

在Javascript中,我有以下代碼:

let args = [1,2,3]; 

function doSomething (a, b, c) { 
    return a + b + c; 
} 

doSomething(...args); 

正如你所看到的,在調用的時候doSomething,我能夠使用...傳播經營者,以「改造」我的論點爲1, 2, 3

現在,我試圖用Java來做同樣的事情。

比方說,我有一個Foo類:

public class Foo { 
    public int doSomething (int a, int b, int c) { 
     return a + b + c; 
    } 
} 

,現在我想打電話給doSomething

int[] args = {1, 2, 3}; 

我想使用類似doSomething (...args)而不是調用doSomething(args[0], args[1], args[2])

我看到這在函數聲明中是可能的,但我不想改變這樣的函數的實現。

+7

不能這樣做。抱歉。 –

+1

這在Java中是不可能的。你可以有另一個需要4個整數參數的方法。在編譯時你不會知道要調用哪一個,因爲它取決於只在運行時知道的列表長度。 – Henry

+0

真的。 Java語法不提供這樣的機制。爲什麼要打擾它? [XY問題?](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)最後,這個問題沒有用。 – Seelenvirtuose

回答

0

Java語言不提供一個操作符來完成這個任務,但是它的類庫有一個功能來執行你所需要的操作。

[來自OP的評論] Foo的開發人員可以自己選擇函數doSomething需要的參數個數。然後,我將能夠構建一個「袋子」的參數,並在方法中注入它。

使用反射API,這是它是什麼。它要求你將參數打包在一個數組中。需要做很多額外的工作,包括打包/解包個別方法參數和方法結果,但是您可以在運行時檢查簽名,構建數組並調用方法。

class Test { 
    public static int doSomething(int a, int b, int c) { 
     return a + b + c; 
    } 
    // This variable holds method reference to doSomething 
    private static Method doSomethingMethod; 
    // We initialize this variable in a static initialization block 
    static { 
     try { 
      doSomethingMethod = Test.class.getMethod("doSomething", Integer.TYPE, Integer.TYPE, Integer.TYPE); 
     } catch (Exception e) { 
     } 
    } 
    public static void main (String[] ignore) throws java.lang.Exception { 
     // Note that args is Object[], not int[] 
     Object[] args = new Object[] {1, 2, 3}; 
     // Result is also Object, not int 
     Object res = doSomethingMethod.invoke(null, args); 
     System.out.println(res); 
    } 
} 

上述代碼打印6(demo)。

0

在java中有變量參數的概念,使用它可以將不同數量的參數傳遞給相同的函數。

我在你的代碼爲例:

public class Foo { 
    public int doSomething (int ...a) { 
     int sum = 0; 
     for (int i : a) 
      sum += i; 
     return sum; 
    } 
} 

現在你可以調用這個函數爲:

doSomething (args) 

欲瞭解更多信息,您可以訪問以下鏈接: http://www.geeksforgeeks.org/variable-arguments-varargs-in-java/

+0

我認爲這種方法是OP暗示的,當他寫道:「我發現這在函數聲明中是可能的,但是我不想改變這個函數的實現。」 – dasblinkenlight

+0

問題是關於完全不同的事情。 –

0

與許多評論相反,例如,通過@JoeC和@Henry,並且不正確的答案,這個可能在Java中。

我想使用類似

doSomething (...args) 

代替調用doSomething的(參數[0],ARGS [1],ARGS [2])。

您需要:

public int doSomething (int ... args) { 
    int sum = 0; 
    for (int i : args) 
    { 
     sum += i; 
    } 
    return sum; 
} 

我想不改變這樣的功能的實現。

Impossible,priori。要麼加入三個參數,要麼加入實際傳遞的參數。對此做出決定。

+2

我認爲這種方法是OP在他寫道「我發現這在函數聲明中是可能的」時暗示的,但我不想改變這樣的函數的實現。 – dasblinkenlight

+0

@dasblinkenlight這是一個矛盾的術語。他想要總結任意數量的論點,或者三個。不是在同一時間。 – EJP

+0

我認爲他想精確地總結三個參數,但是他希望將它們打包在一個三元素數組中以便進行調用。 – dasblinkenlight

0

不幸的是,你不能這樣做。擴展運算符在JavaScript中工作,因爲函數允許接受任何類型的兩個(省略參數是undefined)或太多參數(忽略額外參數)。對於強大而靜態類型的Java,在編譯代碼之前,必須始終確切地知道你要傳遞的參數是多少和什麼類型的。

你或許可以找到一個Java 8的函數接口,方法引用和var-args的方法,但它會需要很多樣板,我甚至不會在這裏發佈它。