7

リスト内の各項目を分割するこの単純な varargs メソッドがあります。

import java.util.*;
class A {
    static long f(long... xs) {
      Arrays.sort(xs);
      long y = 100000000;
      for (int i = xs.length - 1; i >= 0; i--)
        y /= xs[i];
      return y;
    }
    static {
        System.out.println(f(5,2,6,3,9,3,13,4,5));
        long[] xs = new long[]{5,2,6,3,9,3,13,4,5};
        System.out.println(Arrays.toString(xs));
        System.out.println(f(xs));
        System.out.println(Arrays.toString(xs));
    }
}

配列のコピーを渡すことを期待していますが、どうやらそれ自体のローカルコピーではなく、渡した配列を何らかの形で変更しているようです:

$ javac A.java && java A
79
[5, 2, 6, 3, 9, 3, 13, 4, 5]
79
[2, 3, 3, 4, 5, 5, 6, 9, 13]

そこで、この簡単なテスト プログラムを書きました。

class B {
    static void f(Object... os) {
        System.out.println(os);
    }
    static {
        Object os = new Object[]{1,2,3};
        System.out.println(os);
        f(os);
    }
}

そして、それは私が期待することを行います。オブジェクト配列を渡す前に複製しますf(したがって、異なるオブジェクト識別子):

$ javac B.java && java B
[Ljava.lang.Object;@1242719c
[Ljava.lang.Object;@4830c221

では、独自のコピーではなく呼び出し元の配列fを変更するにはどうすればよいでしょうか。A

4

4 に答える 4

3

varargs配列型ですが、要素がパラメーターとして個別に渡される場合、その場で配列を作成できるように構文糖衣を使用します。

つまり、これら 2 つの署名は同一です。

static long f(long... xs) {
static long f(long[] xs) {

ただし、変数引数は配列ではなく個別の要素で呼び出すことができます

もちろん、オンザフライの作成をバイパスして自分で配列を作成して渡すと、配列は変更されます。

于 2013-07-18T16:03:38.387 に答える
1

では、A の f は、それ自体のコピーではなく、呼び出し元の配列をどのように変更するのでしょうか?

独自のコピーはありません。呼び出し元の配列への参照があります。

于 2013-07-18T21:37:16.667 に答える
-1

最終的に、配列はオブジェクトであるため、配列参照自体を変更するのではなく、許可されている内容を変更します。

于 2013-07-18T15:59:22.523 に答える