如何理解数组(JAVA)
先思考几个问题:
1.数组初始化一共有几种方式?
2.数组一定要初始化吗?所谓的对数组初始化究竟是对什么初始化?是数组变量本身吗?
3.声明一个数组过程中,内存是如何分配的?
4.基本类型数组和引用类型数组之间在初始化时的内存分配机制有什么区别?
数组是很多编程语言都存在的一种复合结构,他可以用来存放多个相同类型的变量。java程序中的数组必须先进行初始化才可以使用,所谓初始化,就是为数组对象的元素分配内存空间,并为每个数组元素指定初始值,而在Java中,数组是静态的,数组一旦初始化,长度便已经确定,不能再随意更改。
数组的初始化分为两种:(下面两个例子已经将声明包含在内,实际过程中如果只声明数组,如:int[ ] a;并不能直接使用数组,因为还没有分配内存空间,此时就需要初始化数组)
静态初始化:由程序猿自己确定每个数组元素的初始值,而数组的长度则由系统自己决定,例如:
int[] a = {0,1,2,3,4};
System.out.println(a.length);
a数组由程序员静态初始化,确定了每个元素的值,我们并没有指定数组长度,但是系统会自动计算长度,程序运行结果为5
动态初始化:初始化时由程序猿确定数组的长度,而没一个数组元素的值,则由系统来分配初始值,例如:
int[] b=new int[5];
System.out.println(b[0]);
我们将b数组初始化为一个长度为5的数组,但是并没有指定每一个元素的值,此时输出b[0]将会的到0,因为我们在动态初始化int类型数组后,系统自动分配了默认值0,如果不是int型,而是其他类型时,则:
■数组元素的类型是基本类型中的整数类型(byte、short、int和long),则数组元素的默认值是0。
■数组元素的类型是基本类型中的浮点类型(float、double),则数组元素的默认值是0.0。
■数组元素的类型是基本类型中的字符类型(char),则数组元素的默认值是'\u0000'(Unicode码字符,代表了一个空格)。
■数组元素的类型是基本类型中的布尔类型(boolean),则数组元素的值是false。
■数组元素的类型是引用类型(类、接口和数组),则数组元素的值是null。
我们再来看看第二个问题:
很多人肯定会说是的,数组必须要先初始化才能使用,我在之前也特别用红色字体标注了这句话。但是答案却是不一定需要,要想搞清楚这个问题,我们需要理解数组变量和数组对象的区别。而在认识他们之前需要先了解java的数据类型。java的数据类型分为两种,基本数据类型和引用数据类型。
基本数据类型有八种:byte,short,int,long,float,double,boolean,char.这里不做过多介绍,只需要知道基本数据类型变量包含一个值,这个值的类型与变量相对应。声明基本数据类型后,系统自动在栈上分配一块内存,之后的程序可以直接操作赋值,并存储在栈上;基本类型数据存储在栈内存中这句话是错的.只能说所有局部变量都是存放在栈中的。
引用数据类型:引用型变量的值与基本类型变量不同,变量值是指向内存空间的引用(地址)。所指向的内存中保存着变量所表示的一个值或一组值。这和C语言中的指针很相似,事实上java语言中的引用实际上就是指针,是指向一个对象的内存地址。java所说的不支持指针只是不支持指针的计算,但是指针类型被保留了下来,并称为引用类型。声明引用数据类型后,不可以直接使用,还需要实例化在堆内存中开辟内存空间。
数组变量是一个引用类型的变量,数组变量是指向堆内存当中的数组对象,并不是数组本身。当改变一个数组变量所引用的数组,就可以造成数组长度可变的假象。实际上数组对象本身的长度本没有变化,只是数组变量指向了一个新的数组对象。
所以对于数组变量来说,他并不需要初始化,我们常说的初始化其实是初始化数组对象而非数组变量,有时候我们不进行初始化,而让数组变量指向一个有效的数组对象,数组也可以使用,例如:
int[] a = {0,1,2,3,4};
int[] b;
b=a;
System.out.println(b[1]);
b[1]=99;
System.out.println(a[1]);
我们先对数组a静态初始化,然后声明一个b数组,再将数组a赋给b,此时数组变量b和数组变量a同时指向了一个数组对象,输出b[ 1 ]将得到1,而不会报错。为了验证我们可以将b[ 1 ]的值改为99,此时输出a[ 1 ]也将得到99。
---------------------------------------------------------------------------------------------------------------------------------
声明一个数组时,先在栈中分配一个内存,数组变量被存放在栈中,等到初始化数组时再在堆内存中开辟空间,将数组变量指向数组对象。(欢迎补充。。。。)
---------------------------------------------------------------------------------------------------------------------------------
基本类型数组的初始化:数组元素直接存储在对应的数组元素当中,程序先为数组分配内存空间,再将数组元素的值存入对应的内存量,比较容易理解。
所有基本类型的变量的值都存在栈内存中。这句话是错误的,例如静态初始化一个int类型的数组,数组的元素都是int型,是基本类型的值,但却被存在堆内存中。正确的说法如下:
所有局部变量都存在栈内存中,不管其是基本类型的变量,还是引用类型的变量,都是存储在各自的方法栈区中;但引用类型变量所引用的对象(包括数组、普通Java对象)则总是存储在堆内存中。
基本类型数组的初始化:引用类型数组的数组元素仍然是引用类型,数组元素指向另一块存储了有效对象的内存。