我们知道,数组是一种引用数据类型,数组引用变量只是一个引用,数组元素和数组变量在内存里是分开存放的,下面介绍数组在内存中的运行机制。
1.内存中的数组
数组引用变量只是一个引用,这个引用变量可以指向任何有效的内存,只有当该引用指向有效内存后,才可以通过该数组变量来访问数组元素,因为,引用变量是访问真实对象的根本方式。也就是说,如果我们希望在程序中访问数组,则只能通过这个数组的引用变量来访问它。而实际的数组元素被存储在堆(Heap)内存中,引用变量则被存储在栈(Stack)内存中。
当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会被逐个存入这块栈内存里,当方法执行结束,这个方法的内存栈也就自然被销毁了。所以在所有方法中定义的变量都是存放在内存栈里的;当我们在内存中创建一个对象时,这个对象将被保存在“运行时数据区中”,以便于反复利用,这是因为对象的创建成本通常较大,这个运行时数据区就是堆内存,对内存中的对象不会随着方法的结束而销毁,只有当一个对象没有任何引用变量引用它的时候,系统的垃圾回收机制才会在合适的时候回收它。
如果堆内存中数组不再有任何变量引用指向自己,那么这个数组将成为垃圾,它所占的内存将会被系统的垃圾回收机制所回收。
这里要注意的一点是:在java中,只要类型相互兼容,可以让一个数组变量指向另一个实际的数组,好多人在这儿会认为java数组的长度可变,其实只是这种机制让人产生的错觉。
所以当我们在看待数组的时候,应该把数组看成两个部分:一个是数组引用,也就是在代码中定义的引用变量,另外一个就是实际数组本身,这个部分是在系统内存里的,我们通常无法直接访问它,只能通过数组引用变量来访问。
2.数组元素的初始化
如下列代码:
public class ShuZu{
public static void main(String[] args){
int[] iArr;
iArr = new int[5];
for(int i=0;i<iArr.length;i++){
iArr[i] = i + 10;
}
}
}
上述程序中,首先定义了一个int类型的数组引用变量,当执行 int[] iArr; 后,只是在栈内存中定义了一个空引用,这个引用并未指向任何有效的内存,因此也就无法指定数组的长度,当执行 “iArr = new int[5];” 实现动态初始化后,系统将负责为该数组分配内存空间,并分配默认的初始值,所有数组元素都被默认赋为0。