thinking in java (八) ----- 数组(Array)

一般来说,程序会产生新的对象,有的时候只能到执行期,才能具体知道产生了多少对象,为了存放这些对象的存放(或者说是reference的存放),程序员必须提供对象的存放容器

数组(Array)

数组是java用来存放以及随机访问一连串对象的各种做法中,最有效率的一种。数组是简单的线性序列,其中元素能够被快速访问,不过缺点是:当你产生数组后,你不能改变其size。在java中,数组是一个比较特殊的对象

public class Main{
	public static void main(String[] args) {
		int[] a = new int [10];
		System.out.println(a.getClass().getSuperclass());
		System.out.println(a.getClass().getName());
	}
	
	
}
————————————————————
class java.lang.Object
[I

可以看出Array是Object的直接子类,但是又与一般的java对象有所不同。可以看出其类名是[I,非常滴奇怪,

下面我们再看

public class Main{
	public static void main(String[] args) {
		 System.out.println("Object[]:" + Object[].class);
	        System.out.println("Object[][]:" + Object[][].class);

	        System.out.println("Object:" + Object.class);
	}
	
	
}
++++++++++++++++++++
Object[]:class [Ljava.lang.Object;
Object[][]:class [[Ljava.lang.Object;
Object:class java.lang.Object

从这个实例中我们可以看出数组类和一般java类是不同的,普通的java类是全限定路径名+名字作为自己的唯一标识,但是数组是以[+L+数组元素类全限定路径+类名来作为自己的唯一标识,多了[和L

看下面一组代码:

public class Main{
	public static void main(String[] args) {
		int[] a = new int [10];
		System.out.println(a.getClass().getName());
		
		int[][] a1 = new int [10][10];
		System.out.println(a1.getClass().getName());
	}
	
	
}
++++++++++++++++++++++++++
[I
[[I

通过这个例子我们知道,[代表一维,[[代表二维。可以简单滴说数组的类名由若干个[和"I"组成,下面使用反射机制看一下。

public class Main{
	public static void main(String[] args) {
		int a [] =new int [10];
		Class  myClass = a.getClass();
		System.out.println(myClass.getDeclaredFields().length);
		System.out.println(myClass.getDeclaredMethods().length);
		System.out.println(myClass.getDeclaredAnnotations().length);
		System.out.println(myClass.getDeclaredConstructors().length);
		System.out.println(myClass.getDeclaredClasses().length);
		System.out.println(myClass.getSuperclass());
	 
	}	
}
++++++++++++++++
0
0
0
0
0
class java.lang.Object

可见, [I这个直接子类自身没有申明任何成员方法,构造方法,成员变量,注解等。可以说这就是一个空类。但是我们经常使用.lenth来查看数组的长度,那么为为甚没有length这个成员方法呢。先不管这length,先搞清楚[I在哪申明的吧。

首先[I不是一个标识符,那么这个类肯定是在代码中显式地申明了,只能是在JVM自己运行的时候生成的、java虚拟机这本书中写到:

类加载器先看看数组类是否已经创建,如果创建了就无需创建,如果没有就创建一个,

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

JVM根据元素类型和唯独,创建相应的类

因此,是JVM动态地生成了[I类,再想想,JAVA数组中的元素类型,数量都是未知的,因此必须是动态生成数组类。

 

为了研究length是怎么来的,我们看下一段代码。

public class Main{
	public static void main(String[] args) {
		int a [] =new int [10];
		int i = a.length;
		
	 
	}	
}

其字节码文件:

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

 

参考资料:https://www.cnblogs.com/chenssy/p/3463719.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值