首页 > 编程 > Java > 正文

数组(一):Java数组基础

2019-11-10 17:53:14
字体:
来源:转载
供稿:网友

一、定义数组

数组的定义有三种方式

方式1:推荐 type[] a = new type[元素个数];

方式2:c语言方式 type a[] = new type[元素个数];

方式3:直接初始化 type[] a = new type[]{逗号分隔的初始化值}; 例如:int[] a = new int[]{1,2,3,4,5};

当数组存放的元素不是基本数据类型时,数组内存放的是对象的引用

二、数组是什么?

数组肯定不是基本数据类型,按照我们自己的说法: 数组是一种复合数据类型,它含有一系列相同类型的元素,并且元素的数量是定长的,元素的排列是有序的。

我们可以通过代码来了解一下数组:

int[] a = new int[10];System.out.PRintln(a.getClass().getSuperclass());System.out.println(a.getClass().getName());int[][] b = new int[10][10];System.out.println(b.getClass().getSuperclass());System.out.println(b.getClass().getName());int[][][] c = new int[10][10][10];System.out.println(c.getClass().getSuperclass());System.out.println(c.getClass().getName());//output:class java.lang.Object[Iclass java.lang.Object[[Iclass java.lang.Object[[[Iclass java.lang.Object[C

可见,数组也是一个对象,但是数组的类名却有点奇怪,但是从规律上来看,可以知道: 1. [ 代表数组的维度 2. 最后的大写字母是一种特殊的标识,标识数组的类型,例如int数组的是I,char数组的C,同理double的就是D

也就是说:普通的java类是以 全限定路劲 + 类名 作为自己的唯一标识,而数组时以若干个 [ + 当前数组唯一标识 + 数组权限定路径 + 类名 作为自己的唯一标识,这个说明了,JVM在处理数组时的方式是比较特殊的!

有一个问题值得思考,为什么数组通过.length来获取长度,而String通过.length()来获取长度?

从面向对象的角度来说,直接暴露成员变量是不合理的,我们可以通过反射看看数组的内部结构:

Object[] obj = new Object[10];Class clazz = obj.getClass();System.out.println(clazz.getDeclaredConstructors().length);System.out.println(clazz.getDeclaredFields().length);System.out.println(clazz.getDeclaredMethods().length);try { System.out.println(clazz.getDeclaredField("length")); } catch (NoSuchFieldException e) { System.out.println("没有该域"); } catch (SecurityException e) {}//output:000没有该域

可以看到,数组内部,没有任何的 构造方法、方法、变量,并且连length这个域都没有,而我们就是通过length这个域来获取长度的,这不是很矛盾吗? 这就是JVM做的处理:

使用SUN JDK 1.6编译上述代码,并使用jclasslib打开Main.class文件,得到main方法的字节码:

0 iconst_2 //将int型常量2压入操作数栈 1 newarray 10 (int) //将2弹出操作数栈,作为长度,创建一个元素类型为int, 维度为1的数组,并将数组的引用压入操作数栈 3 astore_1 //将数组的引用从操作数栈中弹出,保存在索引为1的局部变量(即a)中 4 aload_1 //将索引为1的局部变量(即a)压入操作数栈 5 arraylength //从操作数栈弹出数组引用(即a),并获取其长度(JVM负责实现如何获取),并将长度压入操作数栈 6 istore_2 //将数组长度从操作数栈弹出,保存在索引为2的局部变量(即i)中 7 return //main方法返回

可见,在这段字节码中,根本就没有看见length这个成员变量,获取数组长度是由一条特定的指令arraylength实现(怎么实现就不管了,JVM总有办法)。编译器对Array.length这样的语法做了特殊处理,直接编译成了arraylength指令

参考:有关JVM处理Java数组方法的思考

三、二维数组的定义

基本的定义方式有两种形式,如:

方式一:(推荐) type[][] i = new type[2][3];

方式二: type i[][] = new type[2][3];

声明二维数组的时候可以只指定第一维大小,空缺出第二维大小,之后再指定不同长度的数组。但是注意,第一维大小不能空缺(不能只指定列数不指定行数)


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表