如果我声明字符串数组,
String []str = new String[3]; //line 1
它在字符串数组的堆栈中创建一个引用(指针),但我仍然需要str[0] = new String();
来初始化数组中的String。
我知道第1行只是将内存分配给指针,这些指针将用于指向数组中的字符串。
我怀疑的是,这些引用(指针)是否在堆中分配了内存(很可能是,因为使用了 new ),如果是,那么为什么?
答案 0 :(得分:2)
当您声明一个字符串数组String[] str = new String[3];
时,您不只是创建对数组的单个引用。而是为每个字符串创建引用数组。在上面的示例中,将创建三个引用的数组。所有这三个引用都将在堆栈本身中创建。请注意,在JAVA中,所有基本类型和引用都将在堆栈本身中创建。在上面的语句之后,所有三个字符串引用都将指向一个特殊的 null 对象。
现在,当您使用str[0] = new String();
开始创建实际的字符串对象时,将在HEAP中创建新的字符串对象本身。 引用数组中的第一个引用指向新创建的字符串对象。
相反,如果您只是说new String()
,而没有左侧的任何赋值,则会在HEAP中创建新的字符串对象,并且不会对它进行任何引用。这意味着,我们无法在后续步骤中访问新创建的字符串对象。
让我们说,你再次执行类似str[0] = null;
的操作,然后引用再次指向null,我们将不会引用我们之前创建的字符串对象。换句话说,我们不能再访问字符串对象了。
答案 1 :(得分:0)
Java没有指针。但是,如果您使用Object
使用默认toString()
,就像数组一样!,那么您将获得类似参考地址的内容
int[] test = new int[] {1};
int[] test2 = new int[] {1};
System.out.printf("%s %s%n", test, test2);
哪个输出(这里但你的将有两个不同的地址,很可能,每次)
[I@15db9742 [I@6d06d69c
答案 2 :(得分:0)
对数组的引用将在堆栈中。该数组将在堆上。如果将新的引用添加到数组中,则引用将位于堆上(因为数组本身位于堆上)。如果没有其他引用指向同一个String。
PS:自从Java6U23引入Escape Analysis以来,分配可以完成/移动到堆栈本身。
答案 3 :(得分:0)
一般来说,原始对象(int,long,byte等)以及数组引用(String [],int []等)都将在堆栈中。任何复杂的对象(例如String,ArrayList,Cat,Dog,Foo,Double,Long(注意Double和Long中的大写D和L与较小的对象)等都会驻留在堆上。