数组是一种引用数据类型,数组引用变量只是一个引用,数组元素和数组变量在内存里是分开存放的。下面将深入介绍数组在内存中的运行机制。

内存中的数组

数组引用变量只是一个引用,这个引用变量可以指向任何有效的内存,只有当该引用指向有效内存后,才可以通过该数组变量来访问数组元素。

与所有引用变量相同的是,引用变量是访问真是对象的根本方式。也就是说,如果希望在程序中访问数组对象本身,则只能通过这个数组的引用变量来访问它。

实际的数组对象被存储在堆内存中;如果引用该数组对象的数组引用变量是一个局部变量,那么它被存储在栈内存中。数组在内存中的存储示意图如图3所示。

图3  数组在内存中的存储示意图

如果需要访问如图3所示堆内存中的数组元素,则程序只能通过p[index]的形式实现。也就是说,数组引用变量是访问堆内存中数组元素的根本方式。

如果堆内存数组不再有任何引用变量指向自己,则这个数组将成为垃圾,该数组所占的内存将会被系统的垃圾回收机制回收。因此,为了让垃圾回收机制回收一个数组所占的内存空间,可以将该数组变量赋值为null,也就切断了数组引用变量和实际数组之间的引用关系,实际的数组也就成了垃圾。

只要类型相互兼容,就可以让一个数组变量指向另一个实际数组,这种操作会让人产生数组的长度可变的错觉。如下代码所示。

public class ArrayInRam{

public static void main(String[] args){

int[] a = {5,6,1};

int[] b = new int[4];

System.out.println("b数组的长度为:" + b.length);

for(int i = 0,len = a.length; i<len; i++){

System.out.println(a[i]);

}

for(int i = 0,len = b.length; i<len; i++){

System.out.println(b[i]);

}

b = a;

System.out.println("b数组的长度为:" + b.length);

}

}

运行上面代码后,将可以看到先输出b数组的长度为4,然后依次输出a数组和b数组的每个元素,接着会输出b数组的长度为3.看起来视乎数组的长度是可变的,但这只是一个假象。必须牢记:定义并初始化一个数组后,在内存中分配了两个空间,一个用于存放数组的引用变量,另一个用于存放数组本身。下面将结合示意图来说明上面程序的运行过程。

图4  定义并初始化a、b两个数组后内存示意图

当程序定义并初始化了a、b两个数组后,系统内存中实际上产生了4块内存区域,其中栈内存中有两个引用变量:a和b;堆内存中也有两块内存区域,分别用于存储a和b引用所指向的数组本身。此时计算机内存的储存示意图如图5.4所示。

从图4中可以非常清楚地看出a引用和b引用各自所引用的数组对象,并可以很清楚地看出a变量所引用的数组长度是3,b变量所引用的数组长度是4。

当执行上面程序中的代码b = a时,系统将会把a的值赋给b,a和b都是引用类型变量,存储的是地址。因此把a的值赋给b后,就是让b指向a所指向的地址。此时计算机内存的存储示意图如图5所示。

图5  让b引用指向a引用所指向的数组后的存储示意图

从图5中可以看出,当执行了b = a之后,堆内存中的第一个数组具有了两个引用;a变量和b变量都引用了第一个数组。此时第二个数组失去了引用,变成垃圾,只有等待垃圾回收机制来回收它,但是它的长度依然不会改变,直到它彻底消失。

IT兄弟连 Java语法教程 数组 深入数组 内存中的数组的更多相关文章

  1. IT兄弟连 Java语法教程 数组 数组的初始化

    Java语言中数组必须先初始化,然后才可以使用.所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值. 这时有人会问,能不能只分配内存空间,不赋初始值呢?答案是肯定不行的,一旦为数组 ...

  2. IT兄弟连 Java语法教程 数组 多维数组 二维数组的初始化

    二维数组的初始化与一位数组初始化类似,同样可以使用静态初始化或动态初始化. 1)静态初始化 静态初始化的格式如下: 数组名字 = new 数组元素的类型[][]{new 数组元素的类型[]{元素1,元 ...

  3. IT兄弟连 Java语法教程 数组 多维数组 二维数组的声明

    Java语言里提供了支持多维数组的语法.但是这里还想说,从数组底层的运行机制上来看是没有多维数组的. Java语言里的数组类型是引用类型,因此数组变量其实是一个引用,这个引用指向真实的数组内存,数组元 ...

  4. IT兄弟连 Java语法教程 数组 使用foreach循环遍历数组元素

    从JDK5之后,Java提供了一种更简单的循环:foreach循环,也叫作增强for循环,这种循环遍历数组和集合更加简洁.使用foreach循环遍历数组和集合元素时,无需获得数组或集合的长度,无需根据 ...

  5. IT兄弟连 Java语法教程 数组 数组的使用

    数组最常用的用法就是访问数组元素,包括对数组元素进行赋值和取出数组元素的值.访问数组元素都是通过在数组引用变量后紧跟一个方括号([]),方括号里是数组元素的索引值,这样就可以访问数组元素了.访问到数组 ...

  6. IT兄弟连 Java语法教程 数组 数组的声明

    Java语言支持两种语法格式来定义数组: type[] arrayName; type arrayName[]; 对这两种语法格式而言,通常推荐使用第一种格式,因为第一种格式不仅具有更好的语义,而且具 ...

  7. IT兄弟连 Java语法教程 数组 经典案例

    案例需求: 编程实现双色球中奖号码的生成 1)应用知识: ●  数组的声明 ●  数组的使用 ●  for循环 2)需求解析: 在该程序中,需要定义一个长度为7的数组,用来存储中奖号码,使用Rando ...

  8. IT兄弟连 Java语法教程 数组 什么是数组

    数组是编程语言中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值.Java语言的数组则具有其特有的特征, ...

  9. IT兄弟连 Java语法教程 标识符和关键字

    Java语言也和其它编程语言一样,使用标识符作为变量.对象的名字.也提供了一系列的关键字用以实现特别的功能.本小节将详细介绍Java语言的标识符和关键字等内容. 1.分隔符 Java语言里的分号“;” ...

随机推荐

  1. centos重启出现type Control-D to continue【fsck使用】

    VMware vSphere克隆异常/dev/sda2:UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.(i.e.,without -a or -p optio ...

  2. Centos7 下添加开机自启动服务和脚本

    1.添加开机自启服务 #设置jenkins服务为自启动服务 systemctl enable jenkins.service #启动jenkins服务 systemctl start jenkins. ...

  3. 第十六届浙江大学宁波理工学院程序设计大赛 D 雷顿女士与分队hard version(dp)

    题意 链接:https://ac.nowcoder.com/acm/contest/2995/D来源:牛客网 卡特莉接到来自某程序设计竞赛集训队的邀请,来为他们进行分队规划. 现在集训队共有n名选手, ...

  4. [洛谷P1169][题解][ZJOI2007]午餐

    这是题目吗? 显然的DP,讲几个重要的地方 1.贪心:让吃饭时间长的先排队(证明从略) 2.状态: f[i][j][k]代表前i个人,一号时间j,二号时间k显然MLE 所以压缩成f[i][j]代表前i ...

  5. RabbitMQ学习笔记(八、RabbitMQ总结)

    1.什么是消息中间件 Message Queue Middleware,简称MQ,是一种利用高效可靠的消息传递机制进行与平台无关的数据交互的技术. 2.MQ的作用 异步:类似于短信业务,将需要发送的消 ...

  6. echarts堆叠图计算总数和各部分

    app.title = '堆叠条形图'; option = { tooltip : { trigger: 'axis', axisPointer : { // 坐标轴指示器,坐标轴触发有效 type ...

  7. vue 父子父组件通过props传父页面请求后的数据

    父子父组件通过props传父页面请求后的数据,则在父页面的子组件上加上判断数据是否存在即可,如下 <gl-line-bar v-if="oneWeekBetEcharts" ...

  8. SqlException:ConnectionTimeout Expired. The timeout period elapsed during the post-login phase

    linux系统部署.netcore程序后,访问某台sqlserver 2008 R2数据库 Connection Timeout Expired. The timeout period elapsed ...

  9. CSS置换元素和非置换元素

    置换元素: 1. 一个内容 不受CSS视觉格式化模型控制,CSS渲染模型并不考虑对此内容的渲染,且元素本身一般拥有固有尺寸(宽度,高度,宽高比)的元素,被称之为置换元素.  2. 置换元素就是浏览器根 ...

  10. Implement Dependent Reference Properties 实现从属引用属性 (XPO)

    In this lesson, you will learn how to implement properties whose values can depend on other properti ...