我不确定我在这里使用的词汇,如果我错了,请纠正我。
在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])
。
我看到这在功能声明中是可行的,但我不想改变这种功能的实现。
答案 0 :(得分:4)
在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/
答案 1 :(得分:4)
实际上,由于兼容性原因,使用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]));
}
}
所有这些printMany
的呼叫将打印:
一个
两个
三个
它与传播算子并不完全相同,但是在大多数情况下,它已经足够好了。
答案 2 :(得分:3)
Java语言不提供操作员来执行此操作,但其类库可以提供您所需的功能。
[来自OP的评论] Foo的开发者可以自己选择doSomething函数的参数数量。然后我就可以构建一个" bag"参数并将其注入方法中。
使用反射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)。
答案 3 :(得分:2)
不幸的是,你不能这样做。 spread操作符在javascript中工作,因为允许函数接受任意类型的两个(左边的参数是undefined
)或太多的参数(忽略额外的参数)。强大且静态类型的Java必须始终确切地知道在编译代码之前传递的参数的数量和类型。
你可能会发现Java 8的功能接口,方法引用和var-args的hackaround,但它需要这么多的样板,我甚至不会在这里发布它。
答案 4 :(得分:0)
如果你只需要通过这种方式调用几种方法,只需创建一个这样的包装类就可以不用Reflection:
主类(SpreadTest.java):
public class SpreadTest {
public static void main(String []args){
int[] a = {1, 2, 3};
System.out.println(new FooWrapper().doSomething(a)); // 6
}
}
你的包装类(FooWrapper.java):
public class FooWrapper extends Foo {
public int doSomething(int ...a) {
return super.doSomething(a[0], a[1], a[2]);
}
}
具有完成工作的方法的类(Foo.java):
public class Foo {
public int doSomething(int a, int b, int c) {
return a + b + c;
}
}
答案 5 :(得分:0)
// A method that takes a variable number of integer arguments.
static void fun(int ...a)
{
System.out.println("Number of arguments: " + a.length);
// using for each loop to display contents of a
for (int i: a)
System.out.print(i + " ");
System.out.println();
}
// Driver code
public static void main(String args[])
{
// Calling the varargs method with different number
// of parameters
fun(100); // one parameter
fun(1, 2, 3, 4); // four parameters
fun(); // no parameter
}
输出:
Number of arguments: 1
100
Number of arguments: 4
1 2 3 4
Number of arguments: 0
这是在 java 中提供可变数量参数的最简单示例。对于 JavaScript Guyz,这也称为 Rest Operator。但是,如果您了解 JS,请不要与此混淆。 要了解有关 Java 的更多信息,请参阅: [https://www.geeksforgeeks.org/variable-arguments-varargs-in-java/][1]
答案 6 :(得分:-3)
与众多评论相反,例如:通过@JoeC和@Henry以及不正确的答案,这个在中是可能的。
我想使用像
这样的东西
doSomething (...args)
而不是调用doSomething(args [0],args [1],args [2])。
你需要:
public int doSomething (int ... args) {
int sum = 0;
for (int i : args)
{
sum += i;
}
return sum;
}
我不想改变这种功能的实现。
不可能,先验。要么正在添加三个参数,要么添加实际传递的参数。下定决心。