数组和内存控制
一、 数组初始化:
a) 静态初始化: 初始化时由程序员指定数组元素值;系统会自动决定该数组的长度。
b) 动态初始化: 初始化时,程序员指定数组的长度,系统默认为数组元素赋初始化。
//采用静态初始化方式初始化第一个数组 String[] books = new String[] { "仓央嘉措诗集", "人生若只如初见", "当时只道是寻常" }; //采用静态初始化的简化形式初始化第二个数组 String[] names = { "斗鬼神", "杀破狼", "铁碎牙" }; //采用动态初始化的语法初始化第三个数组 String[] strArr = new String[5]; //访问3个数组的长度 System.out.println("第一个数组的长度:" + books.length); System.out.println("第二个数组的长度:" + names.length); System.out.println("第三个数组的长度:" + strArr.length);
注意观察strArr这个变量,该变量使用动态初始化方式,所以每个元素的值为系统默认赋予初始值。
Java系统默认指定初始值的规则如下:
整形(byte,short,int long): 数组元素默认为0;
浮点型(float,double): 数组元素默认值为0.0;
字符型(char): 数组元素默认值为:’\u0000’;
布尔型(boolean): 数组元素默认值为false;
引用类型(类、接口、数组) : 数组元素默认值为null。
注意点: 对一个数组进行初始化时,不要同时使用静态初始化和动态初始化,即不要即指定数组的长度,又为每个元素分配初始值。
二、 数组长度不变:
a) 数组初始化完成后,数组的长度不可改变; 程序可以改变数组引用变量应用的地址,但不能改变堆内存中已有数组的长度。
b) 数组长度: arr.length
三、 基本类型数组初始化:
基本类型的数组,数组元素的值直接存储在对应的数组元素中: 程序为数组元素分配内存空间,再将数组元素的值存入对应的内存中。
//定义一个int[]类型的数组变量 int[] iArr; //静态初始化数组,数组长度为4 iArr = new int[]{2 , 5 , -12 , 20};
程序首先会在方法栈中定义一个iArr的引用变量,此时该变量尚未指向任何有效的堆内存,所以无法使用该引用变量。
之后,程序执行静态初始化,在堆内存中开辟了四块内存空间,分别存储每一个数组元素的值; 空间开辟完成后,数组的长度不可改变。
iArr引用变量将指向堆内存中开辟的空间,可以也只能通过该引用变量来访问操作堆内存空间中的数据。
注意: 所以方法中的变量都是存储在方法栈内存中的; 所有引用变量的值都是存储在堆内存中。
四、 引用类型数组初始化:
引用类型的数组是指数组元素仍然为引用类型,指向另一块堆内存空间,这块堆内存空间里存储了该引用变量所引用的对象。
class Person { //年龄 public int age; //身高 public double height; //定义一个info方法 public void info() { System.out.println("我的年龄是:" + age + ",我的身高是:" + height); } } public class ReferenceArrayTest { public static void main(String[] args) { //定义一个students数组变量,其类型是Person[] Person[] students; //执行动态初始化 students = new Person[2]; System.out.println("students所引用的数组的长度是:" + students.length); //创建一个Person实例,并将这个Person实例赋给zhang变量 Person zhang = new Person(); //为zhang所引用的Person对象的属性赋值 zhang.age = 15; zhang.height = 158; //创建一个Person实例,并将这个Person实例赋给lee变量 Person lee = new Person(); //为lee所引用的Person对象的属性赋值 lee.age = 16; lee.height = 161; //将zhang变量的值赋给第一个数组元素 students[0] = zhang; //将lee变量的值赋给第二个数组元素 students[1] = lee; //下面两行代码的结果完全一样,因为lee和students[1]指向的是同一个Person实例。 lee.info(); students[1].info(); } }分析:
程序执行Person[] students;时,jvm会在栈内存中定义一个引用变量(指针),此时的栈内存尚未指向任何有用的空间。
程序执行students = new Person[2];为students动态初始化,即在堆内存中,开辟两个内存空间,此时,系统会默认为每个数组元素分配默认的初始值null。
此时的students的每个元素都是引用,且此引用并未指向任何有效的内存。
系统接下来定义了zhang和lee两个引用变量,并让他们指向堆内存中的两个Person对象,此时的zhang、lee两个引用变量存储在main方法栈中,而两个Person对象则存储在堆内存中。
接下来,系统让students的两个元素值(引用)分别指向zhang和lee所指向的两个有用Person对象,这样,就可以通过students[0]、students[1]分别访问Person对象了。