Java varargs如何在内存中实现

时间:2018-08-03 12:34:03

标签: java variadic-functions heap-memory stack-memory

据我所知,本地var和args存储在堆栈存储器中,其中包括对象引用,而实际对象存储在堆存储器中。那么,当您使用var-args时会发生什么呢?

public static int[] test(int... x) {
    return x;
}

public static void main(String[] args) {
    int[] a = test(1,2,3,4,5);
    int[] b = test(6,7,8,9,0);
    System.out.println(a);
    System.out.println(b);
    for (int i : a) {
        System.out.println(i);
    }
    for (int i : b) {
        System.out.println(i);
    }

在这里,我相信所有作为参数传递给test中的x的值都存储在堆栈中,因此,当我们调用test(1,2,3,4,5)时,我们将耗尽堆栈空间,相应我们调用test(6,7,8,9,0)应该会在堆栈上引起内存冲突...但是当我运行上面的命令时,我得到以下结果。

[I@2db0f6b2
[I@3cd1f1c8
1
2
3
4
5
6
7
8
9
0

可以看出,由于a的第二次调用生成了test,因此b中的项目没有损坏。两者的存储方式似乎不同。

这是否意味着参数以某种方式存储在堆中?这是否意味着任何形式为function(param)的调用都可以转换为param的值(原始或内存引用),而不必位于堆栈存储器上?

2 个答案:

答案 0 :(得分:4)

变量只是数组顶部的语法加糖-即,使用int...参数与int[]相同。 像所有数组一样,该数组驻留在堆上,并在堆栈中向下传递对该数组的引用。

答案 1 :(得分:2)

x...只是x[]的语法糖。认为它的工作过程与原始数组完全相同。

  

如果引用本身是的成员,则可以将其存储在堆中   一个类或对象,或者如果它是一个   方法。如果原始类型是原始类型,则可以将它们存储在堆中   类或对象的成员。 -Source