国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

關(guān)于java數(shù)組的深度思考

2019-11-18 15:24:32
字體:
供稿:網(wǎng)友

  剛剛開始接觸java數(shù)組的人都會聽到一句類似的話:java是純面向?qū)ο蟮恼Z言,他的數(shù)組也是一個對象。于是乎,筆者就按照一個對象的方式來使用數(shù)組,心安理得。直到我接觸到C的數(shù)組后,才發(fā)現(xiàn)將數(shù)組作為一個類來使用在實(shí)現(xiàn)上是多么的“不自然”。

  
  首先我們看一下表面現(xiàn)象,數(shù)組創(chuàng)建的時候采用的是如下語句:

  MyClass[] arr = new MyClass[9];

  而普通類采用的是如下語句:

  MyClass obj = new MyClass();

  就是說,創(chuàng)建數(shù)組的時候不使用小括號傳參。使得數(shù)組和普通類看起來就有很多不同,因?yàn)樾±ㄌ柪锏膮?shù)是傳遞給構(gòu)造方法的,進(jìn)而讓人感覺數(shù)組類是沒有構(gòu)造方法的。

  
再往深了想,還有很多讓人感覺不自然的東西。可以肯定的是,java確實(shí)將數(shù)組作為了一個類來處理。還是用上面的例子說明:

  可以通過以下方法得到MyClass[]的Class實(shí)例:arr.getClass()或MyClass[].class。這樣,我就可以向數(shù)組類里面“窺探”了。

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

  
  打印出來的結(jié)果是0;證實(shí)數(shù)組類確實(shí)沒有構(gòu)造方法。

  
  假如強(qiáng)行執(zhí)行clazz.newInstance();就會得到下面的錯誤。

  java.lang.InstantiationException: [Larraytest.MyClass;

  證實(shí)數(shù)組類不能夠通過普通的反射方式來創(chuàng)建一個實(shí)例。

  
  再看看數(shù)組類的“廬山真面目”:

  System.out.println(clazz);

  輸出是:

  [Larraytest.MyClass

  對Java Class文件結(jié)構(gòu)稍有了結(jié)就知道,這個字符串的意思就是一個元素類型為arraytest.MyClass的一維數(shù)組。也就是說,數(shù)組類型不是和普通類一樣,以一個全限定路徑名+類名來作為自己的唯一標(biāo)示的,而是以[+一個或者多個L+數(shù)組元素類全限定路徑+類來最為唯一標(biāo)示的。這個()也是數(shù)組和普通類的區(qū)別。而這個區(qū)別似乎在某種程度上說明數(shù)組和普通java類在實(shí)現(xiàn)上有很大區(qū)別。因?yàn)閖ava虛擬機(jī)(java指令集)在處理數(shù)組類和普通類的時候,肯定會做出區(qū)分。筆者猜想,可能會有專門的java虛擬機(jī)指令來處理數(shù)組。

  既然我們可以得到數(shù)組的Class類實(shí)例,就說明肯定需要調(diào)用ClassLoader的 defineClass(不一定非要是loadClass方法)方法,來構(gòu)造一個Class實(shí)例。java虛擬機(jī)規(guī)范規(guī)定,任何一個可以被加載的類,假如其類文件存儲在文件系統(tǒng)上,那么一個*.class文件只能存儲一個類信息,也就是說,數(shù)組類的信息不可能以類文件的形式存儲在本地磁盤上(否則任意一個類都要配有255個數(shù)組類了.....),既然這樣,那就說明java虛擬機(jī)肯定內(nèi)置了一塊用來聲明數(shù)組類的數(shù)據(jù)(不管是幾級數(shù)組)。這是符合java虛擬機(jī)規(guī)范的,規(guī)范規(guī)定class類數(shù)據(jù)可以來自任意介質(zhì),包括本地磁盤、網(wǎng)絡(luò)、數(shù)據(jù)庫、內(nèi)存等等。

  分析到這里,我基本上可以肯定:java對數(shù)組對象化的操作的支持是指令級的,也就是說java虛擬機(jī)有專門針對數(shù)組的指令。數(shù)組的Class類實(shí)例是java虛擬機(jī)動態(tài)創(chuàng)建動態(tài)加載的,其結(jié)構(gòu)與普通java類的Class實(shí)例有一些不同。

  JDK API中有一個java.lang.reflect.Array類,這個類提供了很多方法(絕大多數(shù)是native方法,這在另一個方面證實(shí)了java對數(shù)組的支持是專用指令支持的,否則用本地方法干嘛^_^),用來彌補(bǔ)我們對數(shù)組操作的局限性。

  下面這句話用來創(chuàng)建一個一維的、長度為10的、類型為arraytest.MyClass的數(shù)組:

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

  下面這句話用來創(chuàng)建一個二維的、3乘5的、類型為arraytest.MyClass的數(shù)組:

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

  當(dāng)然你可以用一個數(shù)組的引用指向上面的二維數(shù)組,這里我們用一個Object的引用指向他。
使用的時候,我們也是可以利用Array類提供的方法來實(shí)現(xiàn):

  System.out.println(Array.getLength(arrObj);//第一維長度為3
  System.out.println(Array.getLength(Array.get(arrObj, 2)));//第二維長度為5,這里假如寫3,就會得到你意想之中的java.lang.ArrayIndexOutOfBoundsException

  打印結(jié)果是如我們所想的:

  3
  5

  對于數(shù)組的Class類實(shí)例,還有一些希奇的現(xiàn)象:

  在運(yùn)行代碼 java.lang.reflect.Field fieldarr = clazz.getField("length");的時候,會拋出異常:java.lang.NoSuchFieldException: length,這似乎在說數(shù)組類沒有l(wèi)ength這個域,而這個域其實(shí)是我們用的最多的一個(也就是說這個域是肯定存在的)。筆者認(rèn)為關(guān)于數(shù)組的Class類實(shí)例、數(shù)組的實(shí)現(xiàn)等,還有很多“貓膩”在里面。
 
  順便說一句,java數(shù)組最多只能是255維的。這個讓人看到了C的影子,嘿嘿?!癑ava把數(shù)組當(dāng)作一個java類來處理”說起來輕易,用起來自然,但是細(xì)細(xì)想來,還是有很多不簡單的地方。



發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 长白| 淄博市| 平江县| 临泉县| 聊城市| 师宗县| 清新县| 繁昌县| 赞皇县| 华亭县| 诸城市| 广宁县| 白玉县| 阜宁县| 朝阳县| 清河县| 台山市| 休宁县| 镇雄县| 根河市| 珠海市| 容城县| 夏津县| 临澧县| 苍溪县| 周至县| 墨江| 左权县| 德惠市| 邯郸市| 安泽县| 纳雍县| 大新县| 渑池县| 绥芬河市| 庆安县| 绥中县| 神池县| 闸北区| 东海县| 宝清县|