在Java编程中,数组是一种能够存储多个相同类型数据的集合。使用数组可以有效地组织和处理数据集合。
声明一个数组需要指定元素的类型,后面跟着空括号[]
。初始化数组时,可以使用new
关键字,后跟数组的大小。例如,创建一个存储5个整数的数组:
int[] scores = new int[5];
数组中的每个元素在初始化时都会被赋予默认值。对于基本数据类型int
,其默认值是0
。
通过索引访问数组中的元素,索引从0
开始。例如,访问第一个元素使用scores[0]
,第二个元素使用scores[1]
,依此类推。
public class Main {
public static void main(String[] args) {
// 5位同学的成绩:
int[] ns = new int[5];
ns[0] = 68;
ns[1] = 79;
ns[2] = 91;
ns[3] = 85;
ns[4] = 62;
}
}
使用数组的.length
属性可以获取数组中元素的数量。例如:
int arrayLength = scores.length; // 返回5
在声明数组时,可以直接指定数组的元素,这样编译器会自动计算数组的大小。例如:
int[] scores = {80, 90, 70, 100, 60};
这种方式不仅简洁,而且避免了手动计算数组大小的麻烦。
如果尝试访问一个不存在的索引,程序会在运行时抛出ArrayIndexOutOfBoundsException
。例如,尝试访问scores[5]
将会导致错误,因为数组的有效索引范围是0
到4
。
数组是引用类型,这意味着当你将一个数组赋值给另一个数组变量时,你复制的是数组的引用,而不是数组本身。因此,对数组的修改会影响所有引用该数组的变量。
int[] original = new int[]{1, 2, 3};
int[] copy = original;
copy[0] = 5; // 修改后,original和copy的第一个元素都变成了5
我们观察下面的代码:
public class Main {
public static void main(String[] args) {
// 5位同学的成绩:
int[] ns;
ns = new int[] { 68, 79, 91, 85, 62 };
System.out.println(ns.length); // 5
ns = new int[] { 1, 2, 3 };
System.out.println(ns.length); // 3
}
}
数组的大小本身是不会改变的。在Java中,数组的大小是固定的,一旦声明并初始化了数组,其长度就确定了。当我们谈论数组“大小变”的时候,实际上是指数组引用的变化。
对于数组ns
来说,执行ns = new int[] { 68, 79, 91, 85, 62 };
时,它指向一个5个元素的数组:
执行ns = new int[] { 1, 2, 3 };
时,它指向一个新的3个元素的数组:
在这个过程中,ns
不再指向原来的5元素数组,而是转向了新的3元素数组。这并不意味着原来的5元素数组被改变了或者其大小被调整了,而是说原来的数组不再与ns
变量关联。原来的数组仍然存在于内存中,但是没有变量直接引用它,因此它可能在之后的某个时刻被垃圾回收器回收。
字符串数组
当数组中存储的是引用类型而非基本类型时,修改数组元素的行为会有所不同。这是因为引用类型存储的是对象的引用地址,而不是对象本身的值。以字符串为例,我们可以深入理解这一行为。
首先,我们定义一个字符串数组:
String[] names = {
"ABC", "XYZ", "zoo"
};
在这个数组中,names
实际上包含了三个引用,每个引用指向一个字符串对象。这些对象分别是”ABC”、”XYZ”和”zoo”。
当我们对数组中的某个元素进行赋值操作时,例如names[1] = "cat";
,这里发生的事情是:
- 原来的引用,即
names[1]
指向的字符串对象”XYZ”,并没有被改变。字符串对象”XYZ”仍然存在于内存中,但其引用已经被names
数组中的元素所抛弃。 names[1]
现在指向了一个新的字符串对象”cat”。这意味着,通过names[1]
我们可以访问到新的字符串对象”cat”。- 由于字符串在Java中是不可变的(immutable),原来的字符串对象”XYZ”在内容上并没有被修改。它只是不能再通过
names
数组的第二个位置来访问了。
这种改变引用的行为是引用类型数据在数组中操作的一个典型特点。与基本类型不同,基本类型的值是直接存储在数组中的,修改数组元素会直接改变存储在该位置的值。而对于引用类型,修改数组元素实际上是改变了引用指向的对象,原有对象的内容保持不变,只是失去了通过该数组元素的访问路径。