Java varargs 是如何在内存中实现的

Posted

技术标签:

【中文标题】Java varargs 是如何在内存中实现的【英文标题】:How are Java varargs implemented in the memory 【发布时间】:2019-01-11 08:32:56 【问题描述】:

据我所知,本地变量和参数存储在堆栈内存中,其中包括对象引用,而实际对象存储在堆内存中。那么当你使用 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);
    

这里我相信x中作为参数传递给test的所有值都存储在堆栈中,因此当我们调用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

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

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

【问题讨论】:

可变参数是传递数组作为参数的语法糖。所以它的工作方式与test(new int[] 1, 2, 3, 4, 5) 相同。 docs.oracle.com/javase/tutorial/java/javaOO/… 感谢您的文档! 几乎任何与 Java 相关的东西都可以通过谷歌搜索“java 教程”来解释,并查看官方 Oracle Java 教程的 5 首热门文章。当你可以使用谷歌时,你的空闲时间是惊人的。这就是我为找到本教程所做的。我只是用谷歌搜索“Java varargs 教程” 【参考方案1】:

Varags 只是数组顶部的语法糖化 - 即,使用 int... 参数与 int[] 相同。 像所有数组一样,数组驻留在堆上,您可以在堆栈上向下传递对它的引用。

【讨论】:

@Hulk 是的,谢谢。我猜是意识流打字。【参考方案2】:

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

如果引用本身是 一个类或对象,如果它是一个局部变量,则在堆栈上 方法。并且原始类型可以存储在堆中,如果它们是 类或对象的成员。 - Source

【讨论】:

以上是关于Java varargs 是如何在内存中实现的的主要内容,如果未能解决你的问题,请参考以下文章

命令建议是如何在 bash shell 中实现的?

fseek() 是如何在文件系统中实现的?

隐写术是如何在php中实现的

这是如何在 swift 4 中实现的?

HTML5 地理定位 API 是如何在浏览器中实现的?

如何在 TypeScript 中实现的接口中进行构造函数重载?