int[] arr = { 1, 2, 3, 4 };
在内存中的存储方式:
┌───┬───┬───┬───┐
arr───?│ 1 │ 2 │ 3 │ 4 │
└───┴───┴───┴───┘
执行arr = new int[] { 7, 8, 9 };
时,它指向一个新的3个元素的数组:
arr ──────────────────────┐
│
▼
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ │ 1 │ 2 │ 3 │ 4 │ │ │ 7 │ 8 │ 9 │ │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
但是,原有的4个元素的数组并没有改变,只是无法通过变量arr
引用到它们而已,字符串也是如此。
String buff = "banana";
┌───────────┐
ns───?│ "banana" │
└───────────┘
arr0 ─────┐
▼
┌───┬───┬───┬───┐
┌───┐ ┌──?│ 1 │ 2 │ 3 │ 4 │
ns ────?│???│──┘ └───┴───┴───┴───┘
├───┤ ┌───┬───┬───┬───┐
│???│─────?│ 5 │ 6 │ 7 │ 8 │
├───┤ └───┴───┴───┴───┘
│???│──┐ ┌───┬───┬───┬───┐
└───┘ └──?│ 9 │10 │11 │12 │
└───┴───┴───┴───┘
String[] buff = { "ABC", "XYZ", "zoo" };
┌──────────────────────────┐
┌───┼─────────────────┐ │
│ │ ▼ ▼
┌───┬─┴─┬─┴─┬──┬──────┬──┬─────┬──┬────┬──┐
buff ───?│???│???│???│ │"ABC"│ │"XYZ"│ │"zoo"│
└─┬─┴───┴───┴──┴──────┴──┴─────┴──┴─────┴──┘
│ ▲
└────────────────┘
它相当于一个二维数组。
对names[1]
进行赋值,例如buff[1] = "cat";
,效果如下:
┌─────────────────────────────────────────────────┐
buff │ ┌─────────────────────────────────┐ │
│ │ │ │ │
▼ │ │ ▼ ▼
┌───┬───┬─┴─┬─┴─┬───┬───────┬───┬───────┬───┬───────┬───┬───────┬───┐
│ │???│???│???│ │ "ABC" │ │ "XYZ" │ │ "zoo" │ │ "cat" │ │
└───┴─┬─┴───┴───┴───┴───────┴───┴───────┴───┴───────┴───┴───────┴───┘
│ ▲
└─────────────────┘
这里注意到原来names[1]
指向的字符串"XYZ"
并没有改变,仅仅是将names[1]
的引用从指向"XYZ"
改成了指向"cat"
,其结果是字符串"XYZ"
再也无法通过names[1]
访问到了。
由以上结构得知,一维数组及字符串
直接指向数组元素地址,多维数组及字符串数组
间接指向数组元素地址。
数组传参时,传的是数组指向的地址,字符串
首先指向元素所在的地址,传参之后,改变字符串
,接收方的值不会改变,因为原字符串
指向新的地址,参数仍指向原来的地址。
下例:
public class Test {
static String name;
static void get(String names) {
name=names;
}
public static void main(String[] args) {
Test t = new Test();
String names="xiaoMing";
t.get(names);//name为xiaoMing
names="xiaoHuang";//此时name是xiaoMing,不变
}
}
查看其地址的变化:
而对于数组及字符串数组
,进行以上类似操作时, 如果将其整体重新new了一次,也就是重新分配了地址,其结果及理论与以上相同。
如果只改变数组或字符串数组
其中的元素,而不是重新给其分配地址,则接收方也跟着改变。双方任意一方对这个对象的修改,都会影响对方。
因为传参时传递的是地址,一维数组
,改变其中的元素并不会影响地址,而同样指向这个地址的接收方自然也会被影响。
对于多维数组及字符串数组
,他们和接收方实际指向的是高维部分的地址。低维相当于高位部分的元素,高维地址不发生改变,二者就相当于指向同一个地方,自然也会相互影响。
下例:
public class Test {
static int[][] num;
static void get(int[][] n) {
num=n;
}
public static void main(String[] args) {
Test t = new Test();
int[][] n = { { 2, 5 }, { 7, 4 }, { 8, 5, 2} };
t.get(n);
n[1] = new int[] {1,2};//此时num=2 5 1 2 8 5 2
}
}