程序员的基本功之数组与内存控制
1.数组初始化
Java的数组是静态的,既数组一旦初始化之后,该数组的长度就不可变,Java的数组需要初始化才能使用
数组的初始化就是为数组对象在堆内存中分配一段数组长度的连续的内存空间,并设定初始值(注意并不是数组变量初始化,而是数组对象)
初始化的方式有两种:
1)静态初始化:程序员显示的指定每个数组元素的初始值,并由系统决定数组的长度
2)动态初始化:初始化时只指定数组的长度,由系统为数组元素分配初始值
数组变量本身是引用类型,存储在栈内存中,而数组对象存储在堆内存中
int[] arr1 = new int[]{1,3,4,5};//静态 int[] arr2 = new int[5];//动态
对于动态初始化而言,系统按如下规则给出初始值:
数组元素的类型是基本类型中的整型 byte short int long ,则数组元素的值是0;
数组元素的类型是基本类型中的浮点型 short double ,则数组元素的值是0.0;
数组元素的类型是基本类型中的布尔型 boolean ,则数组元素的值是false;
数组元素的类型是基本类型中的字符型 char ,则数组元素的值是'\u0000';
数组元素的类型是引用类型 ,则数组元素的值是null;
基本数据类型的初始化
对于int[] arr ; arr = new int[]{2,5,-12,20};
当 执行 int[] arr;代码后 内存示意图
当 执行 arr = new int[]{2,5,-12,20}; 代码后
引用类型数组初始化
以一个例子来讲
//Persion类
public class Person { public int age; public double height; public void info(){ system.oup.println(age + "---"+height); } }
public Class Test { public static void main(String[] args){ Person[] students ; students = new Person[2]; Person zhang = new Person; //...setAge setHeight 省略 Person lee = new Person;//...setAge setHeight 省略 students[0] = zhang; students[1] =lee; } }
当执行 Person[] students ;代码后,仅仅是在栈内存定义了一个引用变量,并未指向任何有效的堆内存
当执行
students = new Person[2];
动态初始化以后 ,因为students数组是引用类型的数组,所以动态初始化会给元素默认值null
此时内存图
由图知 此时students数组里的两个元素是引用类型,值为null,并未指向任何有效的内存空间
之后新建了两个Person对象,在栈中有两个Person的引用,分别指向堆内存中的Person对象,此时内存如图
之后
students[0] = zhang;
students[1] =lee;
这两行代码也就是让students[0]和zhang指向同一对象,students[1]和lee指向同一对象 ,如图
此时无论是通过zhang还是通过students[0]修改person 实际上都是修改同一块内存空间
总结:对于引用类型的数组而言,它的数组元素其实就是一个引用类型的变量,因此可以指向任何有效的内存空间(相应类型的内存空间,如本例必须是Person)
方法中定义的变量都属于局部变量,它们都被保存的方法栈中,但数组元素做为数组对象的一部分,总是保存在堆内存中,不管它们的是基本类型的数组元素还是引用类型的数组元素
Java中无法直接修改堆内存中的数据,必须通过对象的引用来操作,保证了程序的健壮性
-------------------------------------------------------------------------------------------------------------------------------
2.多维数组
Java中没有多维数组,实际上Java中的多维数组,以二维数组为例 实际上二维数组就是一个一维数组,只不过这个一维数组的元素还是一个数组而以
关于数组的长度:实际上就是该数组对象所占用内的连续内存空间的长度 如 int[][] arr = new int[4][]; arr.length= 4;