如何在Java中通过引用传递varargs

时间:2014-01-31 09:18:50

标签: java variadic-functions

我正在编写一个接收任意数量参数并返回修改过的方法。我尝试过使用varargs但是它不起作用,在这里你可以看到代码的简化版本:

public static void main(String[] args) {
   String hello = "hello";
   String world = "world";

   addPrefix(hello, world);

   System.out.println("hello: " + hello + "  world: " + world);
}

public static void addPrefix(String... elements) {
   for (int i = 0; i < elements.length; i++) {
      elements[i] = "prefix_" + elements[i];
   }

   for (int i = 0; i < elements.length; i++) {
      System.out.println(elements[i]);
   }
}

印刷结果:

prefix_hello    
prefix_world    
hello: hello  world: world

如您所见,在方法中正确修改了值,但原始变量没有改变。

我查看了很多页面,例如herehere,但似乎Java将vars的值复制到Object[],因此引用会丢失。

我怎么能这样做?

6 个答案:

答案 0 :(得分:5)

Java是pass by value。你无法达到你想要的效果。相反,您可以从addPrefix()函数返回修改后的数组。

public static void main(String args[]) {

    String hello = "hello";
    String world = "world";

    String[] elements = addPrefix(hello, world);

    for (int i = 0; i < elements.length; i++) {
        System.out.println(elements[i]);
    }




}

public static String[] addPrefix(String... elements) {
    for (int i = 0; i < elements.length; i++) {
        elements[i] = "prefix_" + elements[i];
    }

    for (int i = 0; i < elements.length; i++) {
        System.out.println(elements[i]);
    }

    return elements;
}

和输出

prefix_hello
prefix_world
prefix_hello
prefix_world

答案 1 :(得分:2)

array of String[] can be passed to fulfill the vararg requirement - 没有像这样传递数组的副本/克隆,所以在里面改变数组..好吧,到处更改那个数组。但这很难看,特别是因为它增加了“副作用,有时候”。

但是,你不能“通过引用” 1 来创建新数组,因为参数通常像原始代码一样传递给可变方法。< / p>

// but avoid code like this, if possible
String[] words = {"hello", "world"};
addPrefix(words);
System.out.println("hello: " + words[0] + "  world: " + words[1]);

1 如果重新绑定参数会更改调用者中的绑定,那么它只有Call by Reference,即Java does not support。如果使用varargs并不重要。

答案 2 :(得分:0)

"prefix_" + elements[i]创建一个新对象,该对象将放入数组elements中。您必须返回elements才能获得修改过的变量。

答案 3 :(得分:0)

你不能.Java只能按值调用。请参阅How to do call by reference in Java?Is Java "pass-by-reference" or "pass-by-value"?

您可以使用新字符串返回字符串数组并使用此

答案 4 :(得分:0)

你不能这样做

将方法签名更改为List,然后,您可以期望这种传递引用行为。在这里,您将单独传递每个参数,并且java将它们作为内部数组并进一步处理。

答案 5 :(得分:0)

这是一个典型的例子,说明有多少人不知道varargs的工作方式。 Varargs只是一个数组的持有者,该数组是在调用varargs参数的方法时创建的。 为了使我的观点更清楚,我们必须查看varargs的字节码: -

您的代码

String hello = "hello";
String world = "world";
addPrefix(hello, world);

转到此

<强> addPrefix(new String[]{hello, world});

由于您没有引用新创建的数组,因此只需打印原始String对象的值,hello和world

您需要明确返回数组引用并对其进行迭代以查看更改

public static String[] addPrefix(String... elements) {
   for (int i = 0; i < elements.length; i++) {
      elements[i] = "prefix_" + elements[i];
   }

   for (int i = 0; i < elements.length; i++) {
      System.out.println(elements[i]);
   }
  return elements;
}