[Java基础] 数组

来源:互联网 发布:淘宝认证在哪里 编辑:程序博客网 时间:2024/06/06 09:41

理解数组

数组(如:int[])也是一种数据类型,它本身是一种引用类型。Java 的数组要求所有数组元素具有相同的数据类型。因此,在一个数组中,数组元素的类型是唯一的,不能存储多种数据类型的数据。


因为 Java 语言是面向对象的语言,能很好地支持类与类之间的继承关系,这样可能产生一个数组里可以存放多种数据类型的假象:例如有一个水果数组,要求每个数组元素都是水果,实际上数组元素既可是苹果,也可以是香蕉,但这个数组的数组元素的类型还是唯一的,只能是水果类型。这里体现出的继承思想就是:可以说子类一定是父类(苹果一定是水果,香蕉一定是水果),却不能说父类一定是子类(水果一定是苹果,水果一定是香蕉)。


数组初始化

一旦为数组的每个数组元素分配了内存空间,每个内存空间里存储的内容就是该数组元素的值,即使这个内存空间存储的内容是空,这个空也是一个值(null)。不管以哪种方式来初始化数组,只要为数组元素分配了内存空间,数组元素就具有了初始值,初始值的获得由两种形式:一种有系统自动分配,一种有程序员指定。


一旦数组的初始化完成,数组在内存中所占的空间将被固定下来,因此数组的长度将不可改变。即使把某个数组元素的数据清空,但它所占的空间依然被保留,依然属于该数组,数组的长度依然不变。


静态初始化:程序员为数组元素分配初始值,系统决定数组长度。

动态初始化:程序员指定数组长度,系统为数组元素分配初始值。

静态初始化和动态初始化不要同时使用,也就是说不要在进行数组初始化时,既指定数组的长度,也为每个数组元素分配初始值。


内存中的数组

定义数组时,在栈内存(stack)分配空间存储“数组的引用变量”

初始化数组时,在堆内存(heap)分配空间存储“数组本身”


基本数据类型数组

// 静态初始化int[] values1 = { 1, 2, 3 };// 动态初始化int[] values2 = new int[3];


引用类型数组

Integer[] integers = new Integer[2];integers[0] = new Integer(1);integers[1] = new Integer(2);


当我们看一个数组的时候,一定要把数组看成两个部分:一个是数组引用,也就是代码中定义的数组引用变量(stack memory);还有一个是数组本身,这个部分是运行在系统内存(heap memory)里的,通常无法直接访问它,只能通过数组引用变量来访问它。


为什么有栈内存和堆内存之分?

方法执行时,都会建立自己的内存栈,方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了。因此,所有在方法中定义的变量都是放在栈内存中的;

当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),此时这个对象依然不会被销毁。只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在合适的时候回收它。


没有多维数组

 Java 语言提供了支持多维数组的语法。但是,如果从数组底层的运行机制上来看,没有多维数组。

 

Java 语言里的数组类型是引用类型,因此,数组变量其实是一个引用,这个引用指向真实的数组内存。数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,这种情形看上去很像多维数组。

// 定义并初始化具有三个int类型的数组int[] one = new int[3];// 定义并初始化具有三个int[]类型的数组int[][] two = new int[3][];

定义一维数组的语法:type[] arrName;

这是典型的一维数组定义语法,其中 type 是数组元素的类型。

把 type 具体成 int[]( int[] 是一种数据类型,用法和普通类型并无区别),就出现了一个二维数组 int[][] arrName;

再把int这个类型扩展到 Java 的所有类型(不包括数组类型),就可以得出二维数组的定义语法;

定义二维数组的语法:type[][] arrName;

多维数组类推即可。

从这里就可以分析出多维数组的本质其实就是“在数组中存储数组”,用“树”结构实现“多维”的概念。

0 0
原创粉丝点击