java数组的初始化分为两种方式:
静态初始化:初始化时由程序员显示指定每个数组元素的初始值,由系统决定数组长度
动态初始化:初始化时程序员只指定数组长度,由系统为数组元素分配初始值。
不管采用哪儿种方式初始化Java数组,一旦初始化完成,该数组的长度就不可变,可以通过length来获取数组的长度信息。
如上图当我们用上面两种方式定义一个数组时,例如 string[ ] one = new string[ ] { '1', '2','3'}; 静态方式初始化 string [ ] two= new string[ 5]; 动态初始化
执行动态初始化的时候,只给定了数组的长度,系统会根据你给的数据类型为数组赋初值
数组元素是整型,则全为0
是浮点类型,则为0.0
是布尔类型,则为false
是引用类型,比如接口,类和数组, 则为Null
one 和two是数组变量,它们存储在左边的栈去中,而数组对象存储在堆内存中
注意; 不要同时使用静态和动态初始化
java数组是静态的,一旦为数组初始化完成,数组元素的内存空间分配结束,我们只能改变数组中的元素值,但无法改变其长度。java的数组变量是一种引用类型的变量,数组变量并不是数组本身,它只是指向堆内存中的数组对象。即使你将 one=two; 让one指向two,one原先指向的那个数组对象还是长度为3,不会变成5。这样操作之后,one原先指向的那个数组对象因为没有引用变量指向它,它会成为堆内存中的垃圾,等垃圾回收机制来收回。
我们说的数组一定要初始化,并不是指数组变量,而是数组对象本身要进行初始化,就是说在堆内存中的数组对象要初始化。例如 string[ ] three; three=one; 我们没有对three进行初始化,但是它指向了已经分配好内存的One数组对象,这是可以的。
所有局部变量都是放在栈内存里保存的,不管是基本类型的变量,还是引用类型的变量,都是存储在各自的方法栈区中,但引用类型所引用的对象总是存储在堆内存中。
对于java而言,堆内存中的对象,不管是数组对象,还是普通的Java对象通常不允许直接访问,为了访问堆内存中的对象,通常只能通过引用变量。
我们比较困惑的地方是,引用类型变量何时是一个栈区的变量,何时是引用实际的java对象? 其实,引用变量实际上是一个指针,只要程序通过引用变量访问属性,或者通过调用引用变量来调用方法,该引用变量将会由它所引用的对象代替。
引用类型数组的初始化:
public class person {
public int age;
public double height;
}
public class refiernecearraytest
{
public static void main/(string [ ] args)
{
person[ ] students; // 引用类型数组
students = new person[2];
person zhang=new person();
zhang.age=23;
zhang.height=190;
person lee=24;
lee.age=19;
lee.height=189;
students[0]=zhang;
students[1]=lee;
}
内存分配关系如下,students是一个引用类型数组,数组元素是引用变量,引用变量再指向具体的对象zhang和lee
此时zhang 和students[0]是指向同一个内存区的。lee和students[1]是指向同一个内存区的。
当数组引用变量指向一个有效的数组对象之后,程序就可以通过该数组引用变量来访问数组对象。java语言不允许直接访问堆内存中的数据,因此无法直接访问堆内存中的数组对象,程序通过数组引用变量来访问数组。需要注意的是main方法声明的变量都属于局部变量,因此它们都被保存在main方法栈中,但数组元素则作为数组对象的一部分,总是保存在堆内存中,不管它是基本类型的数组元素还是引用类型的数组元素。
Java将多维数组看成一维数组来处理。比如声明 int [ ] [ ] a; 初始化多维数组时可以先只初始化最左边的维数。其实length这个函数确切的说不是返回数组的长度,数组length属性返回系统为该数组所分配的连续内存空间的长度,比如int[3][ ] ;其实返回length是4