1 定义
(1) Java数组是一种引用类型,它要求所有数组元素具有相同的数据类型。
(2) 定义一个数组变量且未初始化时,仅仅表示定义了一个引用变量(即指针),该引用变量还未指定任何有效的内存,因此定义数组时不能指定数组的长度,且数组不能使用。
(3) 数组的定义语法
// type表示数组元素的数据类型,建议采用该种方式
type[] arrayName;
// 不建议使用
type arrayName[];
2 初始化
(1) 初始化就是给数组的数组元素分配内存空间,并为每个数组元素赋初值。数组必须初始化之后才可以使用。
(2) 静态初始化
// 数组的静态初始化
public static void main(String[] args) {
/**
* 静态初始化的语法格式:
* type[] arrayName;
* arrayName = new type[]{element1, element2, element3, ...};
*/
// 定义的同时初始化
String[] strArray = {"ios", "linux", "windows"};
// 静态初始化
int[] intArray;
intArray = new int[]{5, 6, 8, 20};
Object[] objArray;
objArray = new Object[]{"Python", "Hello"};
Object[] objArray2;
// String类为定义数组时所指定的数组元素类型Object的子类
// 子类实例是一种特殊的父类实例
objArray2 = new String[]{"Java", "Test"};
}
(3) 动态初始化
// 数组的动态初始化
public static void main(String[] args) {
/**
* 动态初始化只指定数组长度,由系统为每个数组元素指定初始值。
* 不能同时使用静态初始化和动态初始化。
* 动态初始化的语法格式:
* type[] arrayName;
* arrayName = new type[length];
*/
// byte, short, int, long类型的默认值为0
int[] iArray = new int[10];
// float, double类型的默认值为0.0
float[] flArray = new float[10];
// char类型的默认值为'\u0000'
char[] cArray = new char[32];
// boolean类型的默认值为false
boolean[] bArray = new boolean[8];
// 类、接口、数组等引用类型的默认值为null
Object[] books = new String[10];
}
(4) 引用类型的数组初始化
public static void main(String[] args) {
class Person {
public int age;
public double height;
public void info() {
System.out.println("我的年龄是:" + age + ",身高是:" + height);
}
}
Person[] students;
students = new Person[2];
Person zhang = new Person();
zhang.age = 20;
zhang.height = 158;
Person lee = new Person();
lee.age = 16;
lee.height = 181;
students[0] = zhang;
students[1] = lee;
lee.info();
students[1].info();
}
3 使用数组
/**
* Java通过下标/索引访问数组元素,数组元素的索引从0开始。
* 若索引小于0,或者大于等于数组的长度,运行时会出现异常:
* java.lang.ArrayIndexOutOfBoundsException: N(数组索引越界异常)
*/
public static void main(String[] args) {
Object[] bookArray = new Object[4];
bookArray[0] = "Java";
bookArray[1] = "Android";
for (int i = 0; i < bookArray.length; i++) {
System.out.println(bookArray[i]);
}
// 若执行该语句程序会出错
//System.out.println(bookArray[4]);
}
4 数组与内存
下面用上述引用类型的数组初始化中的程序为例,来介绍数组在内存中的运行机制。
(1) 执行代码 Person[] students; 时,仅在栈内存中定义了一个引用变量students,也就是一个指针,该指针并未指向任何有效的内存区。此时内存中的存储示意图如下:
(2) 执行代码 students = new Person[2]; 对数组students进行动态初始化,系统为数组元素分配的默认初始值都是null。此时内存中的存储示意图如下:
(3) 执行接下来的代码定义了zhang和lee两个Person实例,该过程共分配了4块内存,其中栈内存中存储着zhang和lee两个引用变量,堆内存中存储着两个Person实例。此时内存中的存储示意图如下:
(4) 执行代码 students[0] = zhang; students[1] = lee; 将zhang和lee分别赋给students的第1,2个元素,students数组的数组元素将会指向有效的内存区。其中,zhang和students[0]指向同一个内存区,lee和students[1]指向同一个内存区。此时内存中的存储示意图如下:
5 多维数组
public static void main(String[] args) {
/**
* 二维数组的定义和初始化:
* type[][] arrayName;
* arrayName = new type[length][]; // 动态初始化
* arrayName的实质是一个长度为length的一维数组,该数组的数组元素都是type[]类型。
* 由于该数组的数组元素是引用类型(数组类型),故系统给每个元素分配的初始值是null。
*/
// 定义二维数组
int[][] arrI;
// 动态初始化
arrI = new int[4][];
// 遍历数组a,此时a的所有元素初始值为null
for (int i = 0, len = arrI.length; i < len; i++) {
System.out.println(arrI[i]);
}
// 初始化a的第一个元素,该元素是一个数组引用
arrI[0] = new int[2];
arrI[0][1] = 6;
// 遍历a数组的第一个元素(也就是a[0]数组)中的元素
for (int i = 0, len = arrI[0].length; i < len; i++) {
System.out.println(arrI[0][i]);
}
// 定义时动态初始化
float[][] arrFlo = new float[2][3];
for (int i = 0, len = arrFlo.length; i < len; i++) {
for (int j = 0, l = arrFlo[i].length; j < l; j++) {
System.out.println(arrFlo[i][j]);
}
}
// 静态初始化
String[][] arrStr1 = new String[][]{new String[3], new String[]{"hello"}};
// 简化的静态初始化
String[][] arrStr2 = {new String[3], new String[]{"hehehe"}};
}