1 数组与内存控制

本节要点

  • Java 数组的静态特性
  • Java 数组的内存分配机制
  • 初始化 Java 数组的两种方式
  • 初始化基本类型数组的内存分配
  • 初始化引用类型数组的内存分配

趁不是很忙的时候,读读书,多了解些 Java 底层相关的知识。

对于数组,确实是既熟悉又陌生,工作中经常用到,但其内存分配这些底层知识并不是很熟悉。一旦遇到内存泄露这种问题,估计一时半会儿也找不到具体的问题出在哪。

Java 数组在使用之前必须先对其进行初始化
所谓初始化,即为数组对象的元素分配内存空间,并为每个数组元素指定初始值。

当数组的所有元素都被分配了合适的内存空间、并指定了初始值,初始化即完成。程序以后将不能重新改变数组对象在内存中的位置及大小。

从用法上看,数组元素相当于普通变量,程序既可以吧数组元素的值赋给普通变量,也可把普通变量的值赋给数组元素。

1.1 Java 数组的静态特性

Java 语言是典型的静态语言。
当数组被初始化后,其长度是不可变的,因此 Java 数组是静态的。

1.2 数组的初始化的两种方式及内存分配

1) 静态初始化
      显式指定每个数组元素的初始值,由系统决定数组的长度。

2) 动态初始化
      只指定数组长度,即为每个数组元素指定所需的内存空间,由系统为数组元素分配初始值。


注意:不要对数组同时使用静态初始化和动态初始化,即在初始化时,既指定长度,也为每个数组元素分配初始值。


不管用哪种方式,一旦初始化完成,数组元素的内存空间分配即结束,数组的长度就不可变,程序只能改变数组元素的值
通过数组的 length 属性访问数组的长度。

数组在内存中的分配示例:

// 采用静态初始化方式初始化数组
String[] books = new String[]{"疯狂Java讲义",
                              "轻量级Java EE企业应用实战",
                              "疯狂Ajax讲义",
                              "疯狂XML讲义"
                              };
// 采用静态初始化方式的简化形式
String[] names = new String[]{"疯狂Java讲义",
                              "孙悟空",
                              "猪八戒",
                              "白骨精"
                              };                

// 采用动态初始化方式初始化数组
String[] strArr = new String[5];                                       

示例中3个变量及各自引用的数组在内存中的分配如图:

这里写图片描述

Java 的数组变量是一种引用类型的变量,数组变量并非数组本身,它只是指向堆内存中的数组对象(如上图)。因此可以改变一个数组变量所引用的数组:

books = names;
strArr = names;

此时,引用变量和数组对象在内存中的分配如下图:

这里写图片描述

从上图可以看出,已初始化的数组并没有改变,只是数组变量的引用指向改变而已。

所以,对于数组变量来说,它并不需要进行所谓的初始化,在使用该数组变量之前,只要让数组变量指向一个有效的数组对象即可。
需要进行初始化操作的是该引用变量所引用的数组对象。

同理,Java 中的对象引用变量也不需要进行初始化,需要进行初始化操作的是该引用变量所引用的对象。

1.3 基本类型数组的初始化

对于基本类型数组,Java 直接先为数组分配内存空间,再将数组元素的值存入对应的内存里。即数组元素的值是直接存储在对应的数组元素中的。

int[] iArr;
iArr = new int[]{2, 5, -12, 20};

内存中的存储如下图:
这里写图片描述

有些书中说“基本类型变量的值存放在栈内存中”,
准确的说应该是:所有局部变量(包括基本类型的变量、引用类型的变量)都是存放在栈内存,存储在各自的方法战区中;
引用类型变量所引用的对象(包括数组、Java 对象)则存储在堆内存中。

堆内存中的对象通常不允许直接访问,只能通过引用变量进行访问。

1.4 引用类型数组的初始化

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

Person[] students = new Person[2];
students[0] = zhang;
students[1] = lee;

内存存储如下图:

这里写图片描述

另外,多维数组的本质依然是一维数组。
在使用数组时,应从内存控制的角度来把握程序,不要仅仅停留在代码表面。



参考资料:
疯狂Java:突破程序员基本功的16课-数组与内存控制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值