这里深入学习数组的静态特征、Api
数组的初始化
- 首先在java中,数组变量是引用类型的变量,数组则是真正存储数据的工具。即数组变量存储在栈中,而真正的数组存储在堆中,数组变量存储的是数组的访问地址。
- 数组一旦初始化成功,其长度不可变。而所谓的初始化就是对数组在堆中分配一串连续的内存空间,并为每个数组元素赋初始值。由于数组一旦初始化其长度不能改变,所以在java中,数组在初始化时必须给定长度(给定元素其实质也是给定长度)初始化有以下两种方式:
- 静态初始化:数据类型[] 数组名称 = {值, 值, …};(完整格式:数据类型[] 数组名称 = new 数据类型[]{值, 值, …})也就是直接给数组赋值。
- 动态初始化:数组类型[] 数组名 = new 数据类型[数组长度]; 也就是先给定长度,然后由系统赋初始值。动态初始化赋初始值规则
- 数组元素的类型是(byte、short、int、long)时,数组初始值为0
- 数组元素的类型是(float、double)时,数组初始值为0.0
- 数组元素的类型是(char)时,数组初始值为'\u0000'
- 数组元素的类型是(boolean)时,数组初始值为false
- 数组元素的类型是引用类型时,数组初始值为null
- 上面说到数组变量不等于数组本身,即数组变量只是指向当前数组的引用。那么,由于数组长度不能改变,那么只要改变数组变量指向的数组,那么就可以实现变相的改变数组长度。即当前数组变量指向了新的数组,不再指向之前的数组,就改变了数组的长度。(这点与js等动态语言不同,js的数组长度是可变的)
- 根据第3条,很容易想到,怎么动态始化数组。由于数组的创建是必须伴随着初始化的,但数组变量不同于数组,其只是指向数组。那么可以先定义数组变量,在程序中使其指向已初始化好的数组即可。也就是变相的动态初始化数组。
- 以上都能理解,那么就会出现一个问题。就是元素是基本类型的数组很容易初始化,元素本身长度(字节数)确定,数组长度确定,那么在堆中很容易开辟一块确定连续空间分配给数组。那么如果元素是引用类型,数组应该被分配多大的内存空间呢?由上面可知,数组变量是引用类型,数组变量是指向数组的引用,那么同理,元素是引用类型,那么数组只要存储指向的对象的引用变量就可以了,这时长度就被确定了下来。即数组存储引用类型时,其存储的不是真真正正的对象,而是引用变量。所以这也解释了为什么引用类型的数组初始化的值是null,即数组存储了固定数量的不指向任何对象的引用变量,当给这个数组内的元素赋值时,直接让数组内的引用变量指向这个对象即可,这样就可以通过数组访问到真正的对象。
- 到这里很容易想到,java中多维数组是怎么回事。其实质就是第五条。例如二维数组就是多个一维数组,三维数组就是多个二维数组。即(类型)[][]等于多个(类型)[] ,(类型)[][][]等于多个(类型)[][]。因为数组本身就是引用类型的,所以高维数组只要存储指向低一维数组的引用变量就可以了,依次往下推,直到存储真正的对象(基本类型)或者指向真正对象的引用(引用类型)。这就是多维数组的实质。同样,多维数组(二维或者更高维)初始化时只要初始化最高维的数组即可,其他维数组可不用直接初始化。即要指定最左侧的方括号长度。如:
int[][][][] a = new int[4][][][];
网友评论