JAVA 数组类型

JAVA 数组 官方文档说明http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html

转自 http://blog.sina.com.cn/s/blog_62b8fc330100p5ol.html

4.5 数组类型

数组是编程语言中最常见的一种数据结构,它可用于存储多个数据,一个数据被称为数组元素,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的数据。Java语言的数组则具有它特有的特征,下面将详细介绍Java语言的数组。

4.5.1 理解数组:数组也是一种类型

Java的数组要求所有数组元素具有相同的数据类型。因此,在一个数组中,数组元素的类型是唯一的,即一个数组里只能存储一种数据类型的数据,而不能存储多种数据类型的数据。

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

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

Java的数组既可以存储基本类型的数据,也可以存储引用数据类型的数据。只要所有数组元素具有相同类型即可。

值得指出的是:数组也是一种数据类型,它本身是一种引用类型。例如int是一个基本类型,但int[](这是定义数组的一种方式)就是一种引用类型了。

学生提问:int[]是一种类型吗?怎么使用这种类型呢?

答:没错,int[]就是一种数据类型,与int类型、String类型类似,一样可以使用该类型来定义变量,也可以使用该类型进行类型转换等,使用int[]类型来定义变量、进行类型转换时与使用其他普通类型没有任何区别。int[]类型是一种引用类型,创建int[]类型的对象时也就是创建数组,则需要使用创建数组的语法。

 

4.5.2 定义数组

4.5.2 定义数组

Java语言支持两种语法格式来定义数组:

type[] arrayName;
type arrayName[];

对这两种语法格式而言,通常推荐使用第一种格式。因为第一种格式不仅具有更好的语意,也具有更好的可读性:对于type[] arrayName;方式,很容易理解这是定义一个变量,其中变量名是arrayName,而变量类型是type[],前面已经指出:type[]确实是一种新类型,与type类型完全不同(例如int类型是基本类型,但int[]是引用类型)。因此,这种方式既容易理解,也符合定义变量的语法。但第二种格式:type arrayName[]的可读性就差了,看起来好像定义了一个类型为type的变量,而变量名是arrayName[],这与真实的含义相去甚远。

可能有些读者非常喜欢type arrayName[];这种定义数组的方式,这可能是因为早期某些计算机读物的误导,从现在开始就不要再使用这种糟糕的方式了。

C#就不再支持type arrayName[]这种语法,它只支持第一种定义数组的语法。越来越多的语言不再支持type arrayName[]这种数组定义语法。

数组是一种引用类型的变量,因此使用它定义一个变量时,仅仅表示定义了一个引用变量(也就是定义了一个指针),这个引用变量还未指向任何有效的内存,因此定义数组时不能指定数组的长度。而且由于定义数组仅仅只是定义了一个引用变量,并未指向任何有效的内存空间,所以还没有内存空间来存储数组元素,因此这个数组也不能使用,只有对数组进行初始化后,才可以使用。

定义数组时不能指定数组的长度。

4.5.3 数组的初始化

4.5.3 数组的初始化

Java语言中数组必须先初始化,然后才可以使用。所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值。

学生提问:能不能只分配内存空间,不赋初始值呢?

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

数组的初始化有两种方式:

静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定需要的数组长度。

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

静态初始化

静态初始化的语法格式如下:

arrayName = new type[]{element1, element2 , element3 , element4 ...}

在上面的语法格式中,前面的type就是数组元素的数据类型,此处的type必须与定义数组变量时所使用的type相同,也可以是定义数组时所使用的type的子类;并使用花括号把所有的数组元素括起来,多个数组元素之间以英文逗号(,)隔开,定义初始化值的花括号紧跟[]之后。值得指出的是:执行静态初始化时,显式指定的数组元素值的类型必须与new关键字后type类型相同,或者是其子类的实例。下面代码定义使用了这三种形式类进行静态初始化:

程序清单:codes/04/4-5/TestArray.java
//
定义一个int数组类型的变量,变量名为intArr.
int[] intArr;
//
使用静态初始化,初始化数组时只指定数组元素的初始值,不指定数组长度。
intArr = new int[]{5, 6, 8 , 20};
//
定义一个Object数组类型的变量,变量名为objArr.
Object[] objArr ;
//
使用静态初始化,初始化数组时数组元素的类型是定义数组时数组元素类型的子类
objArr = new String[] {"Java" , "
李刚"};
Object[] objArr2 ;
//
使用静态初始化 
objArr2 = new Object[] {"Java" , "
李刚"};

因为Java语言是面向对象的编程语言,能很好地支持子类和父类的继承关系:子类实例是一种特殊的父类实例。在上面程序中,String类型是Object类型的子类,即字符串是一种特殊的Object实例。关于继承更详细的介绍,请参考本书第5章。

除此之外,静态初始化还有如下简化的语法格式:

arrayName = {element1, element2 , element3 , element4 ...}

在这种语法格式中,直接使用花括号来定义一个数组,花括号把所有数组元素括起来形成一个数组。

实际开发过程中,可能更习惯将数组定义和数组初始化同时完成,如下代码(程序清单同上):

//数组的定义和初始化同时完成,使用简化的静态初始化写法
int[] a = {5, 6 , 7, 9};

动态初始化

动态初始化只指定数组的长度,由系统为每个数组元素指定初始值,动态初始化的语法格式如下:

arrayName = new type[length];

在上面语法中,需要指定一个int整型的length参数,这个参数指定了数组的长度,也就是可以容纳数组元素的个数。与静态初始化相似的,此处的type必须与定义数组时使用的type类型相同,或者是定义数组时使用的type类型的子类。下面代码示范了如何进行动态初始化(程序清单同上):

//数组的定义和初始化同时完成,使用动态初始化语法
int[] prices = new int[5];
//
数组的定义和初始化同时完成,初始化数组时元素的类型是定义数组时元素类型的子类
Object[] books = new String[4];

执行动态初始化时,程序员只需指定数组的长度,即为每个数组元素指定所需的内存空间,系统将负责为这些数组元素分配初始值。指定初始值时,系统按如下规则分配初始值:

数组元素的类型是基本类型中的整数类型(byteshortintlong),则数组元素的值是0

数组元素的类型是基本类型中的浮点类型(floatdouble),则数组元素的值是0.0

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

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

数组元素的类型是引用类型(类、接口和数组),则数组元素的值是null

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

数组初始化完成后,就可以使用数组了,包括为数组元素赋值,访问数组元素值和获得数组长度等。

 

http://book.51cto.com/art/200809/89190.htm

4.5.4 使用数组

4.5.4 使用数组

数组最常用的用法就是访问数组元素,包括对数组元素进行赋值和访问数组元素的值,访问数组元素都是通过在数组引用变量后紧跟一个方括号([]),方括号里是数组元素的索引值,这样就可以访问数组元素了。访问到数组元素后,就可以把一个数组元素当成一个普通变量使用,包括为该变量赋值和取出该变量的值,这个变量的类型就是定义数组时使用的类型。

值得指出的是,Java语言的数组索引是从0开始的,也就是说,第一个数组元素的索引值为0,最后一个数组元素的索引为数组长度减1。下面代码示范输出数组元素的值,以及为指定数组元素赋值(程序清单同上):

//输出objArr数组的第二个元素,将输出字符串"李刚"
System.out.println(objArr[1]);
//
objArr2的第一个数组元素赋值
objArr2[0] = "Spring";

如果访问数组元素时指定的索引小于0,或者大于等于数组的长度,编译程序不会出现任何错误,将运行时出现异常:java.lang.ArrayIndexOutOfBoundsException: 2(数组索引越界异常),在这个异常提示信息后有一个int整数,这个整数就是程序员试图访问的数组索引。下面代码试图访问的数组元素索引等于数组长度,将引发数组索引越界异常(程序清单同上):

//访问数组元素指定的索引等于数组长度,所以下面代码将在运行时出现异常
System.out.println(objArr2[2]) ;

学生提问:为什么要我记住这些异常信息?

答:编写一个程序,并不是独指在电脑里敲出这些代码,还包括调试这个程序,使之可以正常运行。没有任何人可以保证自己写的程序总是正确的,因此调试程序是写程序的重要组成部分,调试程序的工作量往往超过编写代码的工作量。如果根据错误提示信息,准确定位错误位置,并排除程序错误是程序员的基本功。培养这些基本功需要记住常见异常信息,以及其对应的出错原因。

所有数组都提供了一个length属性,通过这个属性可以访问到数组的长度,一旦获得了数组的长度后,就可以通过循环来遍历该数组的每个数组元素,下面代码示范了输出prices数组(动态初始化的int[]数组)的每个元素的值(程序清单同上):

//使用循环输出pricese数组的每个数组元素的值
for (int i = 0; i < prices.length ; i ++ )
{
System.out.println(prices[i]);
}

执行上面代码将输出50,因为prices数组执行的是默认初始化,因为数组元素是int类型,系统为int类型的数组元素赋值为0

下面代码将示范为动态初始化的数组元素进行赋值,并通过循环方式输出每个数组元素(程序清单同上):

//对动态初始化后的数组元素进行赋值
books[0] = "Struts2
权威指南";
books[1] = "
轻量级J2EE企业应用实战";
//
使用循环输出books数组的每个数组元素的值
for (int i = 0 ; i < books.length ; i++ )
{
System.out.println(books[i]);
}

上面代码将先输出字符串"Struts2权威指南""轻量级J2EE企业应用实战",然后输出两个null,因为books使用了动态初始化,系统为所有数组元素都分配一个null作为初始值,后来程序又为前两个元素赋值,所以看到程序的输出结果。

从上面代码中不难看出,初始化一个数组后,相当于同时初始化了多个相同类型的变量,通过数组元素的索引就可以自由访问这些变量(实际上都是数组元素)。使用数组元素与使用普通变量并没有什么不同,一样可以对数组元素进行赋值,或者取出数组元素的值。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值