Java传播运算符

Ham*_*bot 24 java

我不确定我在这里使用的词汇,如果我错了,请纠正我.

在Javascript中,我有以下代码:

let args = [1,2,3];

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

doSomething(...args);
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在调用时doSomething,我能够使用...spread运算符来"转换"我的参数1, 2, 3.

现在,我正在尝试用Java做同样的事情.

假设我有一Foo节课:

public class Foo {
    public int doSomething (int a, int b, int c) {
        return a + b + c;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想打电话给doSomething:

int[] args = {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

我想用一些东西doSomething (...args)而不是打电话doSomething(args[0], args[1], args[2]).

我看到这在函数声明中是可能的,但我不想改变这样一个函数的实现.

Krz*_*sik 14

实际上,出于兼容性原因,使用 varargs 的方法的签名function(Object... args)等效于使用数组声明的方法function(Object[] args)

因此,为了将任何集合传递和传播到需要可变参数的函数,您需要将其转换为数组:

import java.util.Arrays;
import java.util.stream.Stream;

public class MyClass {
  
  static void printMany(String ...elements) {
     Arrays.stream(elements).forEach(System.out::println);
  }
  
  public static void main(String[] args) {
    printMany("one", "two", "three");
    printMany(new String[]{"one", "two", "three"});
    printMany(Stream.of("one", "two", "three").toArray(String[]::new));
    printMany(Arrays.asList("foo", "bar", "baz").toArray(new String[3]));
  }
}
Run Code Online (Sandbox Code Playgroud)

所有这些调用printManywill 打印:

它与扩展运算符并不完全相同,但在大多数情况下,它已经足够好了。


Nis*_*tap 8

在Java中,有一个可变参数的概念,使用它可以将不同数量的参数传递给同一函数。

我以您的代码为例:

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

现在您可以将该函数调用为:

doSomething (args)
Run Code Online (Sandbox Code Playgroud)

有关更多信息,您可以访问以下链接:http : //www.geeksforgeeks.org/variable-arguments-varargs-in-java/

  • 问题是完全不同的事情。 (4认同)
  • 我认为这种方法就是OP在写“我看到这在函数声明中是可能的,但我不想改变这样一个函数的实现”时所暗示的。 (3认同)

das*_*ght 5

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码显示6(demo)。