主要讨论一下,一维数组。关于多维数组,请举一反三!!!!!
1. 数组
Java中,数组是引用类型数据,可以看做是对象,数组中的每个元素相当于该对象的成员变量。
数组中的元素,可以是任何数据类型(基本数据类型或者引用类型)。
数组可以分为一维数组和多为数组。
2. 数组的初始化
数组的初始化分为两步,即声明数组和为数组分配空间(此时也可以为数组手动赋值),如下:
如果,此时打印a的各元素的内容,可以看出a[0]~a[4]都是0,这就说明如果不为数组手动赋值的话,它默认有个初始值(即下面所讲的<3>默认初始化)。关于初始值的大小可以见下表:
对于数组的元素是引用类型,默认初始值是null,如例子:
注意:
声明数组的同时不可以为数组指定长度,如下就会报错:
<1> 静态初始化:在定义数字的同时就为数组元素分配空间并赋值
<2> 动态初始化:数组定义与为数组分配空间和赋值的操作分开进行
<3> 默认初始化:数组是引用类型,它的元素相当于类的成员变量,因此数组分配空间后,每个元素也被按照成员变量的规则被隐士初始化。
3. 匿名数组
形如new int[] {1, 2};形式称之为匿名数组,但是匿名数组一定要赋值给数组对象,不可以单独出现在代码中,否则报错。需要这样:
4. 数组与内存
声明数组的时候,不会为该数组分配地址空间,此时数组引用为null,除非你使用new或者静态创建数组的时候,才会为其分配空间。栈空间上是数组引用,堆中是引用的成员(元素)。
使用默认方式将各元素初始化为0。再看看引用类型数组内存分配情况,此时内存分配:
此时,内存分配情况:
因为s[0]~s[2]也均是引用类型,所以默认值为null。所以记住:引用类型的数组的每一个元素都需要实例化,否则会出现null值。对于本例是String,所以实例化String有两种赋值方式,即直接赋值和new String().这里采用后者。
要明白:s[0]~s[2]在堆内存中存放的是地址,分别指向各自的成员。内存分布:
举个实例:
分析下面代码的内存,见下面的图:
5. 数组与增强for循环
增强for循环是JDK新增特性,用法很简单。举个例子吧!
其实等效下面效果:
注意:增强for循环中的临时变量如上面的i,s一定要与数组类型一致。
6. 数组的复制
数组的复制,就是对数组的一份拷贝,只是内容的拷贝,不会影响各自的引用(内存),不管该数组是引用还是基本数据类型的。使用System.arraycopy方法,完成复制。JDK中对该方法声明:
不论是基本数据类型之间,还是引用数据类型之间的数组,均可以使用该方法进行数组之间的复制。但是不同类型之间的数组不可以进行该操作,否则报ArrayStoreException异常。详看下面的例子代码:
结果:
引用类型的数组:
结果:
自定义的数组:
结果:
这里,可以看出不管是基本数据类型还是引用类型数组,copy之后不会改变彼此的内存。也就是说,改变任何一方不会影响另一方。
7. 数组的赋值
上面说到数组的复制,这里谈谈数组的赋值。
先看基本数据类型的。
结果:
再看引用类型:
结果:
结果:
以上例子,可以看出赋值之后,数组彼此指向同一个地址空间,换句话说,改变其中一个数组的内容会影响另一个。
8. 比较数组大小
主要使用Arrays类的equals方法,这里看看比较两个字节数组大小的源码:
另外,该方法还可以比较对象类型的数组的大小:
好了,仔细分析一下该类的其它equals的方法吧!!