数组及其内存管理——数组初始化

来源:互联网 发布:轩辕传奇神器数据图 编辑:程序博客网 时间:2024/06/05 18:10

1、 数组初始化

        如果程序需要多个类型相同的变量时,就可以考虑定义一个数组。Java语言的数组变量时引用类型的变量,因此具有Java引用变量的特性。


1、1 Java数组静态特性

        Java语言是典型的静态语言,因此Java数组是静态的,即当数组被初始化之后,其所占的内存空间、数组长度均是不可变的。Java程序中的数组必须经过初始化后才能够使用,所谓初始化,即创建实际的数组对象,也就是在内存中为数组对象分配空间,并未每个数组元素指定初始值。

数组的初始化有以下两种方式:

  1. 静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统来决定数组长度。

    1. 静态初始化:初始化时由程序员指定数组长度,由系统为每个数组元素分配初始值。

    注意:Java中数组一旦初始化完成,其长度就不可改变。但可以通过数组的length属性来访问数组的长度。
    public class ArrayTest {public static void main(String[] args) {String[] books = new String[] {  //采用静态初始化方式初始数组"book1","book2","book3"};String[] strArr = new String[5];  ////采用动态初始化方式初始数组System.out.println("第一个数组的长度:" + books.length);System.out.println("第二个数组的长度:" + strArr.length);}}

    输出结果为:
    第一个数组的长度:3
    第二个数组的长度:5
            Java语言的数组变量时引用类型的变量,books和strArr数组在内存的分配示意图如下所示。

            从上图可以知道,对于静态初始化方式,程序员无须指定数组长度,但要指定数组的元素,长度由系统来决定。对于动态初始化方式,程序员只需要指定数组的长度,即为每个数组元素指定所需的内存空间,系统将负责为这些数组元素分配初始值。
    注意:不要同时使用静态初始化和动态初始化方式。也就是说,不要再进行数组初始化时,既指定数组的长度,又为每个数组元素分配初始值。
           Java数组是静态的,一旦数组初始化完成,数组元素的内存空间分配即结束,程序只能改变元素的值,而无法改变数组长度。需要指出的是,Java的数组变量是一种引用的变量,数组元素并不是数组本身,它只是指向堆内存中的数组对象。因此,可以改变一个数组变量所引用的数组,这样可以造成数组长度可变的假象。
           例如:

    import java.util.Arrays;public class ArrayTest2 {public static void main(String[] args) {String[] books = new String[] {  //采用静态初始化方式初始数组"book1","book2","book3"};String[] strArr = new String[5];  ////采用动态初始化方式初始数组strArr = books;System.out.println("第一个数组的长度:" + books.length);System.out.println("第二个数组的长度:" + strArr.length);System.out.println("srtArr:" + Arrays.toString(strArr));}}

    输出结果为:
    第一个数组的长度:3
    第二个数组的长度:3
    srtArr:[book1, book2, book3]
           上面代码中将strArr数组变量指向books数组变量所引用的数组,原来strArr数组变量所引用的数组长度依然是5,但是不再有任何引用变量引用该数组,因此它将会变成垃圾,等着垃圾回收机制来回收。此时,books和strArr数组在内存的分配示意图如下所示。



    1、2 关于数组的初始化

            Java的数组变量只是引用类型的变量,它并不是数组对象本身,只要让数组变量指向有效的数组对象,程序中即可使用该数组对象。

    import java.util.Arrays;public class ArrayTest3 {public static void main(String[] args) {int[] strArr = new int[]{1 , 2 , 3 , 4};  //定义并初始化一个数组int[] number;  //定义一个数组number = strArr;System.out.println("number:" + Arrays.toString(number));number[2] = 5;System.out.println("strArr:" + Arrays.toString(strArr));}}

    输出结果为:
    number:[1, 2, 3, 4]
    strArr:[1, 2, 5, 4]
           程序定义了number数组变量之后,并没有立刻进行初始化过程。当程序执行number = strArr;之后,number变量指向strArr变量所引用的数组,此时两个变量都引用同一个数组对象,strArr和number数组在内存的分配示意图如下所示。


    注意:对数组执行初始化,其实并不是对数组变量执行初始化,而是在堆内存中创建数组对象,也就是为该数组对象分配一块连续的内存空间,这块连续的内存空间的长度就是数组的长度。上面程序中的number变量在执行number = strArr;之后,会直接指向一个已经存在的数组,因此number变量可以使用。Java程序中的引用变量并不需要经过所谓的初始化操作,需要进行初始化的是引用变量所引用的对象。需要指出的是,Java的局部变量必须由程序员赋初始值,因此如果定义了局部变量的数组变量,程序必须对局部的数据变量进行赋值,即使赋值为null。


    1、3 基本类型数组的初始化

            对于基本类型数组而言,数组元素的值直接存储在对应的数组元素中。初始化过程为:程序直接先为数组分配内存空间,再将数组元素的值存入对应内存中。

    public class ArrayTest4 {public static void main(String[] args) {int[] strArr;strArr = new int[]{1 , 2 , 3 , 4};}}
           上面代码对应的内存空间示意图如下所示。

            实际上,不管是基本类型的变量还是引用类型的变量,都是存储在各自的方法栈中的。但引用类型的变量所引用的对象(包括数组、普通Java对象)总是存储在堆内存中。对于Java而言,堆内存中的对象通常是不允许直接访问的,为了访问堆内存中的对象,通常只能通过引用变量。


    1、4 引用类型数组的初始化

            引用类型数组的数组元素依然是引用类型,因此数组元素里存储的还是引用,它指向另一块内存,这块内存里存储了该引用变量所引用的对象。

    class Person{      public int age;  //年龄      public double height;  //身高      public void info() {  //自我介绍         System.out.println("年龄:" + age + ",身高:" + height);      } }public class ArrayTest5 {   public static void main(String[] args) {     Person[] students = new Person[2];  //定义并初始化数组     Person li = new Person();  //创建一个Person实例,并赋给li变量     li.age = 13;     li.height = 120.3;     Person wang = new Person();  //创建一个Person实例,并赋给wang变量     wang.age = 17;     wang.height = 160.5;     students[0] = li;  //将li变量的值赋给第一个数组元素     students[1] = wang;  //将wang变量的值赋给第二个数组元素     students[0].info();     students[1].info();   }}

    输出结果为:

    年龄:13,身高:120.3
    年龄:17,身高:160.5
           执行代码之后,li和students[0]指向同一个内存去,而且它们都是引用类型的变量,因此通过li和students[0]来访问Person实例的属性和方法效果完全一样,同时,无论修改li还是students[0]的属性或者方法,势必也会相互影响,因为修改的其实是同一块内存区域。同理,wang和students[1]也是同样的效果。内存示意图如下所示。


    1 0
    原创粉丝点击