隨筆-14  評論-1  文章-4  trackbacks-0

          Java基礎:初步探討Java語言類加載機制

          發布時間:2007.11.08 04:51???? 來源:賽迪網技術社區????作者:baocl

          記得在剛學JAVA的時候,類的加載機制和初始化順序經常被弄的糊里糊涂,其實當我們不太了解某些事情的時候,不防去做一做實驗,讓代碼的運行結果說話,這或許能幫助我們更好地了解一些事情.今天我們就用一些代碼來看一下類是如何被加載的,并且當有繼承關系的時候,類的加載順序又是怎么樣的.

          先看代碼吧


          /*
          ?* Test4.java
          ?*
          ?* Created on 2007-9-21, 9:33:31
          ?*
          ?* To change this template, choose Tools | Templates
          ?* and open the template in the editor.
          ?*/

          package test1;

          /**
          ?*
          ?* @author hadeslee
          ?*/
          public class Test4 {
          ??? private void testClassForName(String name) throws ClassNotFoundException{
          ??????? Class c=Class.forName(name);
          ??? }
          ??? private void testNewInstance(String name) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
          ??????? Class c=Class.forName(name);
          ??????? Object obj=c.newInstance();
          ??????? System.out.println(obj);
          ??? }
          ??? public static void main(String[] args)throws Exception {
          ??????? Test4 t=new Test4();
          ??????? t.testClassForName("test1.B");
          ??????? new B();
          ??????? new B();
          ??? }
          }
          class A{
          ??? private int aj;
          ??? {
          ??????? aj=20;
          ??????? System.out.println("A成員初始化塊");
          ??? }
          ??? private static int ai;
          ??? static {
          ??????? ai=10;
          ??????? System.out.println("A靜態初始化塊");
          ??? }
          ??? public A(){
          ??????? System.out.println("A構造函數");
          ??? }
          }
          class B extends A{
          ??? private static int bi;
          ??? static {
          ??????? bi=30;
          ??????? System.out.println("B靜態初始化塊");
          ??? }
          ??? private? int bj;
          ??? {
          ??????? bj=40;
          ??????? System.out.println("B成員初始化塊");
          ??? }
          ??? public B(){
          ??????? System.out.println("B構造函數");
          ??? }
          }
          在代碼里面我們總共有三個類,一個是做測試用的Test4,一個是A,一個是A的子類B,我們在A和B類里面都有很多輸出,一個是靜態初始化的輸出,一個是成員初始化的輸出,一個是在構造函數里面的輸出,從這些輸出我們可以知道代碼的執行順序,以上代碼運行輸出如下:

          A靜態初始化塊
          B靜態初始化塊
          A成員初始化塊
          A構造函數
          B成員初始化塊
          B構造函數
          A成員初始化塊
          A構造函數
          B成員初始化塊
          B構造函數

          從上面我們可以看出,A和B的靜態初始化塊只被執行了一次,也就是類的對象將要被生成的時候,它會執行,并且執行的順序如下:父類的靜態成員,子類的靜態成員,父類的成員變量和構造方法,子類的成員變量和構造方法.當再用這個類生成對象的時候,靜態的部份就不再被調用了.因為靜態是類的所有實例所共享的,所以它在整個虛擬機的生命周期內只執行一次.

          如果我們加上一個t.testClassForName("test1.B");放在main函數的最后面,我們會發現輸出還是和剛剛一樣,沒有任何改變,這個時候,我們知道,當我們調用Class.forName(name);的時候,類是不會自動初始化的,它默認只是把這個類的字節碼讀入內存,但是并沒有初始化這個類.只有我們調用了newInstance()的時候,它才會被初始化.在這里我們再這樣試一下:把A和B生成的class文件去掉,然后再分別調用Class.forName和new B(),看看會怎么樣,我們會發現當我們調用Class.forName的時候,當我們要for的Name找不到的時候,只會拋出ClassNotFoundException,注意,它只是一個異常而已,而當我們new B()的時候,B的class文件卻被我們刪掉了,那就事大了,那就將拋出NoClassDefFoundError,呵呵,它就是一個Error了,這點區別我們可要注意啦,當我們在做這些事情的時候,一個只要捕獲異常就可以了,一個卻需要捕獲一個Error,一般來說,Error級別的錯誤是不希望程序員去捕獲的.了解了類的基本加載順序以及加載機制后,對我們了解JAVA是有一定的幫助的.

          posted on 2008-02-03 16:47 大胃王的BLOG 閱讀(166) 評論(0)  編輯  收藏

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


          網站導航:
           
          主站蜘蛛池模板: 射阳县| 扎赉特旗| 东兰县| 洛宁县| 乐山市| 廊坊市| 陆良县| 大同县| 灵石县| 泰来县| 十堰市| 昭平县| 合川市| 万盛区| 开封市| 余庆县| 分宜县| 辽源市| 汽车| 西吉县| 江油市| 扶绥县| 扬州市| 潼关县| 花垣县| 彩票| 东乡族自治县| 青阳县| 龙井市| 聂拉木县| 上栗县| 内江市| 东乡| 三门峡市| 丁青县| 高邑县| 图们市| 庄河市| 泗洪县| 辉南县| 泰来县|