在java中,数组保存在内存中的什么位置?

在java中,数组保存在内存中的什么位置?,java,arrays,memory,stack,heap,Java,Arrays,Memory,Stack,Heap,如果我有一个函数,在该函数中我声明: Object arr[] = new Object[20]; arr和整个阵列存储在哪里?堆堆栈 声明是在某个函数中还是在main()中重要吗 假设我还有这些命令行: arr[0] = new String("abc"); arr[1] = new List(); 哪里存储了arr[0]和arr[1]?理论上,堆栈有一个指向堆中包含数组本身的位置的指针。数组本身只是一个指针数组,它也指向堆中包含引用对象的位置 在Java中,您几乎可以依赖这样一个事实:每

如果我有一个函数,在该函数中我声明:

Object arr[] = new Object[20];
arr和整个阵列存储在哪里?堆堆栈 声明是在某个函数中还是在main()中重要吗

假设我还有这些命令行:

arr[0] = new String("abc");
arr[1] = new List();

哪里存储了
arr[0]
arr[1]

理论上,堆栈有一个指向堆中包含数组本身的位置的指针。数组本身只是一个指针数组,它也指向堆中包含引用对象的位置

在Java中,您几乎可以依赖这样一个事实:每当您说
new…
,堆中就会创建空间。一般来说,无论何时声明变量,编译器都会在方法上下文中为该变量保留堆栈空间。对于本机类型,该空间将保存表示值的实际字节。对于对象和数组,该变量将保存内存引用

因此,例如,以下对象在堆中为其分配了单独的内存位置:

new Object[20]
new String("abc")
new List() // This contains a reference to an initial array, which is also on the heap.
请注意,
newstring(“abc”)
“abc”
更可取的时候很少,因为字符串文本无论如何都会存在于包的内存中,并且字符串是不可变的。为已经存在于内存中的字符串的精确副本分配额外内存是没有意义的

实际上,唯一需要注意的是编译器根本不必在堆栈上存储局部变量。如果它确定变量的作用域足够短,则可以随意优化堆栈引用,只需为其使用一个寄存器。

需要一个n个字符串的数组

  • 堆上n个对象引用的后续列表
  • n个引用堆上数组的单字符串对象
  • 堆上的n个字符数组

这个数组还有一个引用,可以保存在堆栈上,或者(作为类上的一个字段)在Java中的堆中,基本上在使用
new
关键字时,可以在堆上为要存储的对象分配空间

用于指向该对象的变量包含存储在堆栈上的引用

例如:

                                    // This array object is
                                    // stored on the heap.
String[] arr                      = new String[5];
// This reference (arr) is stored
// in a variable on the stack.
对于像
对象[]
这样的引用类型数组,分配的空间是一个连续的块,足够大,可以存储数组将容纳的引用数量。任何特定的引用,例如位于
arr[0]
的引用,本身都将指向堆上存储单个对象的另一个位置

The array, somewhere on the heap:
[a*][b*][  ][  ][  ]

a (elsewhere on the heap):
"abc"

b (yet another heap location):
[A List object]
唯一的例外是原语数组,如
int[]
:在这种情况下,数组本身仍然是堆上的一个连续块,但数组中的每个位置都包含实际值本身,而不是对堆上另一个位置的引用。

内存图:

框是存储位置(可以存储二进制数)。

箭头是内存引用(即指针)。

确实可能是伟大答案的重复。