疯狂java之数组与内存控制

使用java数组之前必须先对数组对象进行初始化。当数组的所有元素都被分配了合适的内存空间,并指定了初始值时,

数组初始化完成。程序以后将不能重新改变数组对象在内存中的位置和大小。从用法角度来看,数组元素相当于普通变量,

程序既可以把数组元素的值赋给普通变量,也可把普通变量的值赋给数组元素。

1.1数组初始化

数组是大多数编程语言提供的一种复合结构,如果程序需要多个类型相同的变量时,就可以考虑定义一个数组。

Java语言的数组变量时引用类型的变量,因此具有Java独有的特性。

1.1.1Java数组是静态的

Java语言是典型的静态语言,因此Java的数组是静态的,即当数组被初始化之后,该数组的长度是不可变的。Java程序中

的数组必须经初始化才可使用。所谓初始化,就是为数组对象的元素分配内存空间,并为每个数组元素指定初始值。

数组的初始化有以下两种方式。

静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度。

动态初始化:初始化时程序员只指定数组长度,由系统为数组分配初始值。

 

不管采用哪种方式初始化java数组,一旦初始化完成,该数组的长度就不可改变,java语言允许通过数组的length属性来

访问数组的长度

public class T {

	public static void main(String[] args) {
		//采用静态初始化方式初始化第一个数组
		String books[] = new String[]{"java学习笔记","SQL案例解析","研读设计模式"};
		//采用静态初始化的简化形式初始化第二个数组
		String names[] = {"zhangsan","lisi","wangwu"};
		//采用动态初始化的语法初始化第三个数组
		String strArr[] = new String[5];
		
		//访问三个数组的长度
		System.out.println("第一个数组长度: "+books.length);
		System.out.println("第二个数组长度: "+names.length);
		System.out.println("第三个数组长度: "+strArr.length);
	}
}


上面代码声明并初始化了三个数组。这三个数组的长度将会始终不变,程序输出三个数组的长度依次为3,3,5

前面已经指出,java语言的数组变量是引用类型的变量,books,names,strArr这三个变量以及各自引用的数组在

内存中的分配如图所示。

 

从图中可以看出,对于静态初始化而言,程序员无需指定数组长度,指定该数组的数组元素,由系统来决定该数组的长度即可。

例如books数组,为它指定了3个数组元素,那它的长度就是3。

执行动态初始化时,程序员只需指定数组的长度,即为每个数组元素指定所需的内存空间,

系统将负责为这些数组元素分配初始值。指定初始值时,系统将按如下规则分配初始值。

数组元素的类型是基本类型中的整数类型(byte、short、int和long),则数组元素的值是0

数组元素的类型是基本类型中的浮点类型(float、double),则数组元素的值是0.0

数组元素的类型是基本类型中的字符类型(char),则数组元素的值是'\u0000'

数组元素的类型是引用类型(类、接口、和数组),则数组元素的值是null

注意:不要同时使用静态初始化和动态初始化,也就是说,不要在进行数组初始化时,即指定数组的长度,也为每个数组元素分配初始值。

 

java的数组是静态的,一旦为数组初始化完成,数组元素的内存空间分配即结束,程序只能改变数组元素的值,

而无法改变数组的长度。需要指出的是,java的数组变量是一种引用类型的变量,数组变量并不是数组本身,它只是指向堆内存中的

数组对象。因此可以改变一个数组变量所引用的数组,这样可以造成数组长度可变的假象。

假设,在上面程序后面增加如下几行。

books = names;
		strArr = names;
		System.out.println("books数组长度:"+books.length);
		System.out.println("strArr数组长度:"+strArr.length);
		books[1]="李四";
		System.out.println("names数组的第二个元素是:"+names[1]);

上面程序中将books数组变量,strArr数组变量都指向names数组变量所引用的数组,这样做的结果就是books  strArr names

这三个变量引用同一个数组对象。此时,三个引用变量和数组对象在内存中的分配如图


从图可以看出,此时strArr,names和books数组变量实际上引用同一个数组对象。因此,当访问books数组,strArr数组的长度时,

将看到输出3。这很容易造成一个假想:strArr数组的长度从5变成了3,实际上,数组对象本身的长度并没有发生改变,变的是strArr

数组变量。当然,从图中还可以看出,原来books变量所引用的数组长度依然是3,但不再有任何引用变量引用该数组,因此它将会

变成垃圾等着垃圾回收机制来回收。

 

1.1.2数组一定要初始化吗

始终记住:java的数组变量时引用类型的变量,它并不是数组对象本身,只要让数组变量指向有效的数组对象,

程序中即可使用该数组变量

public class T {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//定义并初始化nums数组
		int nums[] = new int[]{3,13,4,6};
		//定义一个prices数组变量
		int prices[];
		//让prices数组指向nums所引用的数组
		prices = nums;
		for(int i=0;i<prices.length;i++){
			System.out.println(prices[i]);
		}
		//将prices数组的第三个元素赋值为100
		prices[2] = 100;
		//访问nums数组的第三个元素 将看到数组100
		System.out.println(nums[2]);
	}

}


从上面代码可以看出,程序定义了prices数组之后,并未对prices数组进行初始化。 当执行int  prices[]之后,程序的内存分配如图

从图可以看出,此时的prices数组还未指向任何有效的内存,未指向任何数组对象,此时的程序还不可使用prices数组变量

当程序执行prices = nums之后,prices变量将指向nums变量所引用的数组,此时prices变量和nums变量引用同一个数组对象

执行这条语句之后,prices变量已经指向有效的内存及一个长度为4的数组对象,因此程序完全可以正常使用prices变量了。

对于数组变量来说,它并不需要进行所谓的初始化,只要让数组变量指向一个有效的数组对象,程序即可正常使用该数组变量。

 

 

 

posted @ 2013-06-12 19:44  爱生活,爱编程  阅读(222)  评论(0编辑  收藏  举报