JAVA中关于数组的深入

*  数组对象的类是什么?

既然数组是对象,那么数组究竟是什么呢?当然,不是java.util.Arrays

public class TestArray {

        private class Dog {

        }

        public static void main(String[] args) {

           int a[] = new int[10];

           int b[] = new int[5];

           //Dog a[][] = new Dog[2][];//[[LTestArray$Dog;

           //int a[][][] = new int[2][][];//[[[I

           //long a[][] = new long[10][];//[[J

           //float a[] = new float[2];//[F

     //String a[][] = new String[10][];

//[[Ljava.lang.String;

           Class clazz = a.getClass();

           System.out.println(clazz.getName());

           Class clazzb = b.getClass();

           System.out.println(clazzb.getName());

        }

}

根据上面的实例,可以得出结论:

ü  数组的类名由若干个’[‘和数组元素类型的内部名称组成,’[‘的数目代表了数组的

维数;

ü  具有相同类型元素和相同维度的数组,属于同一个类,如果两个数组的元素类型相

同,但维度不同那么它们也不属于同一个类,如果一个数组的元素类型和维度相同,但长度不同,那么他们还是属于同一个类;

(2) 数组的类有哪些成员?

实例测试:

public class TestArray {

        private class Dog {

        }

        public static void main(String[] args) {

           int a[] = new int[10];

           Class clazz = a.getClass();

       System.out.println(clazz.getName());

       System.out.println(clazz.getDeclaredFields().length);

       System.out.println(clazz.getDeclaredMethods().length);

    System.out.println(clazz.getDeclaredConstructors().length);

System.out.println(clazz.getDeclaredAnnotations().length);

       System.out.println(clazz.getDeclaredClasses().length);

       System.out.println(clazz.getSuperclass());

        }

}

打印结果:

[I

0

0

0

0

0

class java.lang.Object

    可见,[I这个类是java.lang.Object的直接子类,自身没有声明任何成员变量、成员方法、构造函数和Annocation,可以说:[I就是一个空类。学到这里,我们起码会产生这样一个疑问:为什么连length这个成员变量都没有呢?因为我们经常使用数组.length来获得数组的长度,编译器怎么就没有报错了?

*  数组的类在哪里声明?

类加载器先看看数组类是否已经被创建了。如果没有,那就说明需要创建数组类;如果有,那就无需创建了。

如果数组元素是引用类型,那么类加载器首先去加载数组元素的类。

JVM根据元素类型和维度,创建相应的数组类。

可见,是JVM自己在运行时生成了数组的类对象;再细想,JVM必须动态生成数组类,因为JAVA数组类的数量和元素类型、维度(最多255)有关,可见是无法预先声明好的。

*  没有length这个成员变量!

我们已经发现, JVM没有为数组类生成length这个成员变量,那么Array.length这样的语法如何通过编译,如何执行的呢?

让我们看看字节码吧!编写一段最简单的代码,使用jclasslib查看字节码。

1.public class Main {  

2.    public static void main(String[] args) {  

3.    int a[] = new int[2];  

4.        int i = a.length;  

5.    }  

6.} 

使用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创建数组类,应该就是由newarray这条指令触发的了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值