• 《阿古顿巴》藏语版在藏语卫视首播 2019-09-06
  • 晋中市“三同步”推动互联网治理创新 2019-08-27
  • 法媒:研究称美国人常用药物或增加抑郁风险 2019-08-27
  • 宝贝是地名,你能想到这么浪漫的地名在哪儿吗? 2019-08-15
  • 何树山副省长到方圆机电调研指导工作 2019-08-15
  • 广东快乐十分一期计划:关于java数组的深度思考

    来源:本网整理

    彩票双色球历史开奖结果 www.s9h6.com   刚刚开始接触java数组的人都会听到一句类似的话:java是纯面向对象的语言,他的数组也是一个对象。于是乎,笔者就按照一个对象的方式来使用数组,心安理得。直到我接触到C的数组后,才发现将数组作为一个类来使用在实现上是多么的“不自然”。

      
      首先我们看一下表面现象,数组创建的时候采用的是如下语句:

      MyClass[] arr = new MyClass[9];

      而普通类采用的是如下语句:

      MyClass obj = new MyClass();

      就是说,创建数组的时候不使用小括号传参。使得数组和普通类看起来就有很多不同,因为小括号里的参数是传递给构造方法的,进而让人感觉数组类是没有构造方法的。

      
    再往深了想,还有很多让人感觉不自然的东西??梢钥隙ǖ氖?,java确实将数组作为了一个类来处理?;故怯蒙厦娴睦铀得鳎?/P>

      可以通过以下方法得到MyClass[]的Class实例:arr.getClass()或MyClass[].class。这样,我就可以向数组类里面“窥探”了。

      
      Class clazz = MyClass[].class;
      System.out.PRintln(clazz.getConstrUCtors().length);

      
      打印出来的结果是0;证实数组类确实没有构造方法。

      
      假如强行执行clazz.newInstance();就会得到下面的错误。

      java.lang.InstantiationException: [Larraytest.MyClass;

      证实数组类不能够通过普通的反射方式来创建一个实例。

      
      再看看数组类的“庐山真面目”:

      System.out.println(clazz);

      输出是:

      [Larraytest.MyClass

      对Java Class文件结构稍有了结就知道,这个字符串的意思就是一个元素类型为arraytest.MyClass的一维数组。也就是说,数组类型不是和普通类一样,以一个全限定路径名+类名来作为自己的唯一标示的,而是以[+一个或者多个L+数组元素类全限定路径+类来最为唯一标示的。这个()也是数组和普通类的区别。而这个区别似乎在某种程度上说明数组和普通java类在实现上有很大区别。因为java虚拟机(java指令集)在处理数组类和普通类的时候,肯定会做出区分。笔者猜想,可能会有专门的java虚拟机指令来处理数组。

      既然我们可以得到数组的Class类实例,就说明肯定需要调用ClassLoader的 defineClass(不一定非要是loadClass方法)方法,来构造一个Class实例。java虚拟机规范规定,任何一个可以被加载的类,假如其类文件存储在文件系统上,那么一个*.class文件只能存储一个类信息,也就是说,数组类的信息不可能以类文件的形式存储在本地磁盘上(否则任意一个类都要配有255个数组类了.....),既然这样,那就说明java虚拟机肯定内置了一块用来声明数组类的数据(不管是几级数组)。这是符合java虚拟机规范的,规范规定class类数据可以来自任意介质,包括本地磁盘、网络、数据库、内存等等。

      分析到这里,我基本上可以肯定:java对数组对象化的操作的支持是指令级的,也就是说java虚拟机有专门针对数组的指令。数组的Class类实例是java虚拟机动态创建动态加载的,其结构与普通java类的Class实例有一些不同。

      JDK API中有一个java.lang.reflect.Array类,这个类提供了很多方法(绝大多数是native方法,这在另一个方面证实了java对数组的支持是专用指令支持的,否则用本地方法干嘛^_^),用来弥补我们对数组操作的局限性。

      下面这句话用来创建一个一维的、长度为10的、类型为arraytest.MyClass的数组:

      arraytest.MyClass[] arr = (arraytest.MyClass[]) Array.newInstance(arraytest.MyClass, 10);

      下面这句话用来创建一个二维的、3乘5的、类型为arraytest.MyClass的数组:

      int[] arrModel = new int[]{3,5};
    Object arrObj = Array.newInstance(Sub.class, arrModel);

      当然你可以用一个数组的引用指向上面的二维数组,这里我们用一个Object的引用指向他。
    使用的时候,我们也是可以利用Array类提供的方法来实现:

      System.out.println(Array.getLength(arrObj);//第一维长度为3
      System.out.println(Array.getLength(Array.get(arrObj, 2)));//第二维长度为5,这里假如写3,就会得到你意想之中的java.lang.ArrayIndexOutOfBoundsException

      打印结果是如我们所想的:

      3
      5

      对于数组的Class类实例,还有一些希奇的现象:

      在运行代码 java.lang.reflect.Field fieldarr = clazz.getField("length");的时候,会抛出异常:java.lang.NoSuchFieldException: length,这似乎在说数组类没有length这个域,而这个域其实是我们用的最多的一个(也就是说这个域是肯定存在的)。笔者认为关于数组的Class类实例、数组的实现等,还有很多“猫腻”在里面。
     
      顺便说一句,java数组最多只能是255维的。这个让人看到了C的影子,嘿嘿?!癑ava把数组当作一个java类来处理”说起来轻易,用起来自然,但是细细想来,还是有很多不简单的地方。


  • 本文相关:
  • 让你学习控制住Web2.0的方向盘二
  • Java1.5中新的静态导入特性
  • Java中this的使用
  • MicrosoftVisualStudio.NET系统必备
  • WirelessMessagingAPI(3)
  • “JavaStudioEnterprise7”新功能
  • Java 理论与实践: 用JMX检测应用程序
  • JavaC/Smode--Client
  • EasyJWeb-Velocity脚本简明教程
  • 以全局的固定顺序获取多个锁来避免死锁
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 彩票双色球历史开奖结果 - 频道导航
    Copyright © 2017 彩票双色球历史开奖结果 www.s9h6.com All Rights Reserved
  • 《阿古顿巴》藏语版在藏语卫视首播 2019-09-06
  • 晋中市“三同步”推动互联网治理创新 2019-08-27
  • 法媒:研究称美国人常用药物或增加抑郁风险 2019-08-27
  • 宝贝是地名,你能想到这么浪漫的地名在哪儿吗? 2019-08-15
  • 何树山副省长到方圆机电调研指导工作 2019-08-15
  • 山东快乐扑克3今天 河内5分彩属于什么彩种 甘肃十一选五选号技巧 qq德克萨斯扑克没豆了 福彩3D012路遗漏 足彩和篮彩 快速赛车游戏 青海体育彩票十一选五 上海时时乐走势图号 nba比分显示器 天津快乐10分钟开奖 中国福利彩票2016025期 京东新11选5走势图 大乐透复式注数分解 象棋第一步怎么走最好