<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 51, comments - 17, trackbacks - 0, articles - 9
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    java 數組

    Posted on 2007-04-23 11:06 chenweicai 閱讀(149) 評論(0)  編輯  收藏

    剛剛開始接觸java數組的人都會聽到一句類似的話:java是純面向對象的語言,他的數組也是一個對象。
    于是乎,我就按照一個對象的方式來使用數組,心安理得。直到我接觸到C的數組后,才發現將數組作為一個類來使用在實現上是多么的“不自然”。
    首先我們看一下表面現象,數組創建的時候采用的是如下語句:
    MyClass[] arr = new MyClass[9];
    而普通類采用的是如下語句:
    MyClass obj = new MyClass();
    就是說,創建數組的時候不使用小括號傳參。使得數組和普通類看起來就有很多不同,因為小括號里的參數是傳遞給構造方法的,進而讓人感覺數組類是沒有構造方法的。


    再往深了想,還有很多讓人感覺不自然的東西??梢钥隙ǖ氖牵琷ava確實將數組作為了一個類來處理。還是用上面的例子說明:
    可以通過以下方法得到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的影子,嘿嘿。

    “Java把數組當作一個java類來處理”說起來容易,用起來自然,但是細細想來,還是有很多不簡單的地方呀。 

     


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 69式互添免费视频| 黄色成人免费网站| 亚洲中文字幕无码专区| 理论亚洲区美一区二区三区| 午夜免费福利网站| 相泽南亚洲一区二区在线播放| 国产成人精品免费直播| 国产精品亚洲va在线观看| 亚洲第一区精品观看| 国产97视频人人做人人爱免费| 久久精品国产亚洲5555| 日韩a级无码免费视频| 亚洲欧洲国产精品香蕉网| 中国国语毛片免费观看视频| 国产亚洲一区二区在线观看| 一级特黄aa毛片免费观看| 91精品国产亚洲爽啪在线观看| 成人免费黄色网址| 色噜噜噜噜亚洲第一| 亚洲精品国产精品国自产观看| 中文无码日韩欧免费视频| 亚洲视频在线视频| 岛国片在线免费观看| 一级毛片免费在线播放| 亚洲AV成人片色在线观看| 国产免费丝袜调教视频| 亚洲AV无码一区二区三区鸳鸯影院| 国产啪亚洲国产精品无码| 免费无码VA一区二区三区| 亚洲最大的成人网| 中文字幕亚洲激情| 久久国内免费视频| 成人国产网站v片免费观看| 老汉色老汉首页a亚洲| 日本免费一区尤物| 久久一本岛在免费线观看2020| 中文字幕亚洲综合小综合在线| 亚洲女人被黑人巨大进入| 午夜免费福利小电影| 午夜亚洲乱码伦小说区69堂| 久久亚洲精品人成综合网|