数组及其内存管理

程序需要多个类型相同的变量时可以考虑用数组。

java 数组是引用类型的变量(具有java引用变量的特征)

1.java数组是静态的

当数组被初始化后,该数组占用的内存空间,数组长度都是不可变的。java数组必须初始化才能使用(即创建实际的数组对象,在内存中为数组对象分配内存空间,并为每个数组元素指定初始值)

初始化方式(两种):

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

如:int [] score = new int[]{99,89,79,69,59}; 另一种写法: int [] score = {99,89,79,69,59};

对于静态初始化方式,无需指定长度,指定数组元素,由系统来决定数组的长度。

动态初始化:初始化时只指定数组的长度,由系统为数组元素分配初始值。

如:int [] score = new int[5];

对于动态初始化方式,只需指定长度(即为每个数组元素指定所需的内存空间)系统将负责为这些元素分配初始值。指定初始值时有以下规则:

数组元素是基本类型的整型(byte,short, int,lang),则数组元素的值是0;

数组元素是基本类型的浮点型(float,double),则数组元素的值是0.0;

数组元素是基本类型的布尔型(boolean),则数组元素的值是false;

数组元素是基本类型的字符型(char),则数组元素的值是‘\u0000’;

数组元素是基本类型的引用类型(String,类,接口,数组),则数组元素的值是null;

不论采用哪种方式初始化数组,一旦初始化完成,该数组的长度(score.length)就不可改变。不要同时使用静态初始化和动态初始化。

java数组是静态的,一旦数组初始化完成,数组元素的内存空间分配即结束,程序只能该改变数组元素的值,无法改变数组长度。
javaScript这种动态语言的数组长度是可以动态改变的。

var arr = [];

document.writeln(“arr的长度是:”+arr.length);

arr[2] = 1;

arr[4] = 4;

document.writeln("arr的长度是:"+arr.length);

第一次输出为0,第二次输出为5;先定义一个名为arr的空数组,它的长度是0,然后为arr数组的第三个,第五个元素赋值时,数组长度变成了5。

Java 数组是一种引用类型的变量,数组变量并不是数组本身,它只是指向堆内存中的数组对象,因此可以改变一个数组变量所引用的堆内存中的数组,这样就可以造成数组长度可变的假象。其实变化的是数组变量,而不是该数组变量所指向的内存。如果没有任何变量引用堆中的数组,它就会变成垃圾,等待垃圾回收机制回收。

数组对象和数组变量:

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

如:int [ ] nums = {1,2,3,4,5};

//声明一个prices 数组。

int [] prices;

//让prices数组指向nums所引用的数组。

prices = nums;

System.out.print(prices.lentgh);

结果为5.

数组变量和数组对象:

数组变量类似于C语言中的指针,只是一个引用变量

数组变量,并不需要所谓的初始化,只要让数组变量指向一个有效的数组对象(堆内存中连续的内存空间),程序即可正常使用该数组变量。

数组对象就是保存在堆内存中的连续内存空间

数组执行初始化,其实并不是对数组变量执行初始化,而是在堆内存中创建数组对象(在堆内存中分配一块连续的内存空间,内存空间的长度就是数组元素的个数)。

java 程序中的引用变量不需要经过初始化操作,需要进行初始化的是引用变量所引用的对象(堆内存中的空间)。

 

基本类型数组的初始化:

数组元素的值直接存储在对应的数组元素中,如:int [] score = {99,89,79,69,59};程序直接先为数组分配内存空间,再将数组元素的值存入对应的内存里。

程序运行过程中的“变量”,可以把它理解为一种容器,瓶子用于存储水,而变量用于存储值,也就是数据。

指定类型的瓶子装指定的水,指定类型的变量只能存储指定类型的值。

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

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

如:int [] score  = {1,2,3,4,5};本质上是main栈区的引用变量int [] score,但是使用score.length, score[1]时,系统会自动变为访问堆内存中的数组对象。

究竟何时引用类的变量只是栈内存中的变量本身,何时又变成了引用实际的java对象。规则如下:引用变量本质上只是一个指针,只要程序通过引用变量访问属性,或者通过引用变量来调取方法,该引用变量就会被它的引用的对象替代。

这也是常常会犯的错误(NullPointException);当通过引用变量来访问实例属性,或者调用非静态方法时,如果该引用变量还未引用一个有效的对象(堆内存中的空间),程序就会报空指针异常。

 

引用类型数组的初始化:

引用类型数组的数组元素依然是引用类型的,因此数组元素里存储的还是引用(指向堆内存中的一块内存,这块内存里存储了该引用变量所引用的对象(包括数组和java对象(堆内存的空间))),对于引用类型的数组而言,它的数组元素其实就是一个引用类型的变量,因此可以指向任何有效(强类型的约束)的内存。

 

使用数组:

当数组引用变量指向一个有效的数组对象之后,程序就可以通过该数组引用变量来访问数组对象。java不可以直接访问堆内存中的数据,因此无法直接访问堆内存中的数组对象,只能通过数组引用变量来访问数组。

这样做的目的是为了保证程序更加健壮,如果程序直接访问并修改堆内存中数据,可能会破坏内存中的数据完整性,从而导致程序crash。

数组元素就是变量:只要在已有数据类型之后增加[]符号,就会产生一个新的数组类型,

如:

int  int[]   int类型变成了int[]数组类型   

Student  Student[]  Student类型变成了Student[]数组类型

int[]   int[][] int[]类型变成了int[][]数组类型

当程序需要多个类型相同的变量来保存程序状态时,可以考虑使用数组来保存这些变量。当一个数组初始化完成之后,就相当于定义了多个类型相同的变量。

无论哪种类型的数组,其数组元素其实相当于一个普通变量,把数组类型去掉一组[]后得到的类型就是该数组元素的类型。

如:

int []   数组元素是int 类型的变量

Student[]数组元素是Student类型的变量

int[][] 数组元素是int[]类型的变量。

当通过索引来使用数组元素时,将该数组元素当成普通变量使用即可,包括访问该数组元素的值,为数组元素赋值等。

 

没有多维数组

前面已经指出,只要在已有数据类型之后增加方括号,就会产生一个新的数组类型,如果是int ,增加[] 就是int[] 这个数组类型,如果再以int[]  为已有类型,增加[] 就得到int[][] 类型,依然是数组类型,如果再以int[][]类型为已有类型,增加方括号就得到int[][][]类型,依然是数组类型。

反过来,将数组类型最后一组[] 去掉就得到了数组元素的类型。对于int[][][] 类型的数组,数组元素就是int[][],数组元素就是int[]类型的变量,对于int[] 类型的数组,数组元素就相当于int类型的变量。

上面也是多维数组处理的逻辑,所谓的多维数组(n)就是由n-1维数组对象组成的。

转载于:https://my.oschina.net/u/3701483/blog/1553018

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值