java——数组与内存控制

数组的初始化

java 语言的数组变量是引用类型的变量

java 语言是典型的静态语言,因此 java 数组也是静态的,即当数组被初始化之后,数组长度就不可以改变。

java 数组必须经过初始化才可以使用,有两种初始化方式:静态初始化和动态初始化。一旦初始化完成,该初始化长度不可以改变。

    初始化:为数组对象元素分配内存空间,并为每个元素指定初始值。

两种初始化示例如下。

public class ArrayTest {

    public static void main(String[] args) {
        
        //静态初始化
        String [] books = new String[] {
            "西游记",
            "三国演绎",
            "水浒传",
            "红楼梦"
        };
        
        //静态初始化简化形式
        String [] names = {
                "西游记",
                "三国演绎",
                "水浒传",
                "红楼梦"
        };
        //动态初始化
        String [] date = new String[4];
    }

}

静态初始化方式:

       不需要指定长度,只需要指定数组的元素,由系统来决定数组的长度即可。

动态初始化方式:

       只需要指定数组的长度,即为每个数组元素指定内存空间,系统将为这些元素分配初始值。

       注意:一旦为数组初始化完成,数组元素的内存空间分配就即结束,程序只可以改变数组元素的值,而无法改变数组的长度!

       数组变量只是引用类型的变量,并不是数组本身,它只是指向堆内存中的数组对象。因此,可以改变数组变量所引用的数组,这样就可以造成数组长度可变的假象。

       因此,只要让数组变量指向有效的数组对象,程序中即可以使用该数组变量。

       对数组执行初始化,其实并不是对数组变量执行初始化,而是对数组对象执行初始化。——也就是为该数组对象分配一块连续的堆内存空间,这块连续内存空间的长度就是数组的长度。

       对于java程序中的所有引用变量,都不需要经过所谓的初始化,需要进行初始化操作的是该引用变量所引用的对象。


基本类型数组初始化

//定义一个 int [] 类型的数组变量
int [] iArr;
//静态初始化数组
iArr = new int [] {2,5,-12,20};

当执行 int [] iArr; 时只是在栈中定义了一个未指向任何有效的内存的数组变量。

当执行完 iArr = new int [] {2,5,-12,20};后,数组对象创建成功。此时的内存存储如图1.5. logical RDD 转换成 physical stage

所有的局部变量都是放在栈内存中保存,不管是基本类型的变量还是引用类型的变量,都是存储在各自的方法栈中;但引用类型变量所引用的对象(包括数组、普通的 java 对象)则总是存储在堆内存中。

问题:引用类型变量何时只是栈内存中的变量本身,何时又变为引用实际的 java 对象?

       引用变量本质上只是一个指针,只要程序通过引用变量访问属性或调用方法,该引用变量将会由它所引用的对象代替。

引用类型数组初始化

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

没有多维数组

多维数组初始化代码如下:

 

// 二维数组静态初始化
        int[][] twoArray = { 
                {1,2,3,4,5,6,7},
                {8,9,10,11,12,13,14,15}
                };
        
        int [] arr1 = {1,2,3,4,5,6,7};
        int [] arr2 = {8,9,10,11,12,13,14,15};
        
        
        //二维数组动态初始化  第二个数不指定是会根据实际引用的数组长度,就算指定了也没有意义
        int [] [] twoArr = new int [3] [];
        twoArr[0] = arr1;
        twoArr[1] = arr2;
        for (int i = 0; i < twoArr.length; i++) {
            for (int j = 0; j < twoArr[i].length; j++) {
                System.out.println(twoArr[i][j]);
                //执行结果:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
            }
        }
        //只需要指定 该类型(int [] [])数组的长度就可以
        //int [] [] [] three = new int [2] [] [];
        //三维数组
        int [] [] [] threeArr = {
                twoArr,
                twoArray
        };

 

代码执行完成时的内存存储如下图: 

                            logical RDD 转换成 physical stage        

所谓多维数组,其实只是数组元素依然是数组的 1 维数组, 2 维数组是数组元素是 1 维数组的数组, 3 维数组是数组元素是 2 维数组的数组, 4 维数组是数组元素是 3 维组的数组……N 维数组是数组元素是 N−1 维数组的数组。

小结

       介绍了 Java 数组的静态特征,即 Java 数组一旦初始化完成,该数组长度将不可改变;此外,也介绍了 Java 数组静态初始化、动态初始化的内存分配细节。对于数组变量而言,一定要区分它何时只是数组变量,何时代表数组对象本身。还分析了 Java 多维数组的实质。

疯狂java基本功的16课中的第一课

posted @ 2018-01-31 22:51  TigerExpensive  阅读(272)  评论(0编辑  收藏  举报