java数组注意事项
java数组是对象
java数组有值拷贝和引用传递两种赋值机制
值拷贝
用基本数据类型赋值给数值时,直接拷贝
1 public class test{ 2 public static void main(String[] args) { 3 int [] a = {1,2}; 4 }
此数组在虚拟机中分布如下
引用传递
当数组给数组赋值时,被赋值的数组会得到赋值数组的地址,这两个数组将共用内存空间,如果被赋值的数组原本也指向了一块内存空间,并且这块内存空间没有其他数组再指向,那么这块原本的内存空间将会等待虚拟机来自动回收
1
public class test{ 2 public static void main(String[] args) { 3 int[] a = new int[]{1,3,5,7,8}; 4 int b[] = a; 5 b[0] = 4; 6 System.out.print(a[0]); 7 }; 8 }
a[0] = 4
注意,当数组元素之间赋值,不是引用赋值,如下图
1 public class test1{ 2 public static void main(String[] args) { 3 int a[] = {1,2,3}; 4 int b[] = new int [1]; 5 b[0] = a[0]; 6 b[0] = 5; 7 System.out.print(b[0] + " " + a[0] ); 8 } 9 }
b[0] = 5 a[0] = 1
二维数组内存
假设现在有一个二维数组
int[][] a = new int[2][2]
那么它在jvm内存布局如下
可以看到,这时,栈中的数组指向一个包含此二维数组的每一个一维数组的地址的内存空间,当用户想访问二维数组的某一个元素时,先通过栈中的指针,找到堆中的0x0001,然后在0x0001中,找到该元素所在的一维数组的地址,在通过相应的一维数组的地址来找到对应的一维数组并找到想要访问的元素,所以二维数组实际上像是一维数组的封装,声明格式多了一种
int[] a[]
实际的操作还是通过一维数组来做,实际内存里数据也是保留在每个一维数组内。
当二维数组进行行数不确定的声明时,0x0001包含的是一个个null,当正式进行一维数组的建立时,才有实际的指针
1 int[][] a = new int[2][]//只是开辟了堆中包含每个一维数组的地址的内存空间,且因为还没创建一维数组,此时包含的指针的值都是空,这只是代表会有两个一维数组 2 3 for(int i = 0 ;i <= arr.length;i++)//这个arr.length的值为2,即二维数组第一个下标的值; 4 a[i] = new int [i + 1];//正式创建了一维数组,目前没赋值,且数组是int,所以数据都是默认为0,然后上面说的包含指针的内存空间将存放这些一维数组的地址
注意,由图知道,二维数组的内存可以是不连续的!!!而且由于每个一维数组独立,那么允许一维数组之间元素个数不同。