• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      深入研究Java的類加載機制

      2010-03-22 22:44:09張洪波
      唐山師范學院學報 2010年2期
      關鍵詞:調用實例內存

      趙 宇,張洪波

      (唐山師范學院 計算機科學系,河北 唐山 063000)

      在許多傳統(tǒng)語言中,程序是作為啟動(startup)過程的一部分立刻被加載的。然后是初始化,緊接著程序開始運行。這些語言的初始化過程必須小心控制,以確保static的初始化順序不會造成麻煩。例如,如果某個static在另一個static被初始化之前就可以被有效地使用,那么 C++就會出現問題。Java就不會出現這個問題,因為它采用了一種不同的加載方式。由于 Java中的所有事物都是對象,所以許多動作就變得更加容易,加載動作僅僅是其中之一。每個類的編譯代碼都存在于它自己的獨立的文件中。

      一般來說,“類的代碼在初次使用時才加載”這通常是指知道類的第一個對象被構建時才發(fā)生加載,但是當訪問static數據成員或是static方法時,也會發(fā)生加載。初次使用之處也是靜態(tài)初始化(static初始化)發(fā)生之處。所有的static對象和static代碼段都會在加載時依程序中的順序(即定義類時的書寫順序)依次初始化。當然,static只會被初始化一次。

      Java語言是一種具有動態(tài)性的解釋型編程語言,當指定程序運行的時候,Java虛擬機就將編譯生成的.class文件按照需求和一定的規(guī)則加載進內存,并組織成為一個完整的Java應用程序。Java語言把每個單獨的類 Class和接口Implements編譯成單獨的一個.class文件,這些文件對于Java運行環(huán)境來說就是一個個可以動態(tài)加載的單元,這些文件只在需要使用程序代碼時才會被加載。正是因為 Java的這種特性,我們可以在不重新編譯其它代碼的情況下,只編譯需要修改的單元,并把修改文件編譯后的.class文件放到Java的路徑當中,等到下次該 Java虛擬機器重新激活時,這個邏輯上的 Java應用程序就會因為加載了新修改的.class文件,自己的功能也做了更新,這就是Java的動態(tài)性。

      1 預先加載與依需求加載

      Java運行環(huán)境為了優(yōu)化系統(tǒng),提高程序的執(zhí)行速度,在JRE運行的開始會將 Java運行所需要的基本類采用預先加載(pre-loading)的方法全部加載要內存當中,因為這些單元在Java程序運行的過程當中經常要使用的,主要包括JRE的rt.jar文件里面所有的.class文件。

      當java.exe虛擬機開始運行以后,它會找到安裝在機器上的JRE環(huán)境,然后把控制權交給JRE,JRE的類加載器會將lib目錄下的rt.jar基礎類別文件庫加載進內存,這些文件是 Java程序執(zhí)行所必須的,所以系統(tǒng)在開始就將這些文件加載,避免以后的多次IO操作,從而提高程序執(zhí)行效率。

      相對于預先加載,在程序中需要使用自己定義的類的時候就要使用依需求加載方法(load-on-demand),就是在Java程序需要用到的時候再加載,以減少內存的消耗,因為Java語言的設計初衷就是面向嵌入式領域的。

      2 隱式加載和顯示加載

      Java的加載方式分為隱式加載(implicit)和顯示加載(explicit),上面的例子中就是用的隱式加載的方式。所謂隱式加載就是在程序中用new關鍵字來定義一個實例變量,JRE在執(zhí)行到 new關鍵字的時候就會把對應的實例類加載進入內存。隱式加載的方法很常見,用的也很多,JRE系統(tǒng)在后臺自動的幫助用戶加載,減少了用戶的工作量,也增加了系統(tǒng)的安全性和程序的可讀性。

      相對于隱式加載的就是不經常用到的顯示加載。所謂顯示加載就是有程序員自己寫程序把需要的類加載到內存當中,如下程序代碼所示:

      class TestClass{

      public void method(){

      System.out.println("TestClass-method");

      }

      }

      public class CLTest{

      public static void main(Stringargs[]){

      try{

      Classc=Class.forName("TestClass");

      TestClassobject=(TestClass)c.newInstance();object.method();

      }catch(Exceptione){

      e.printStackTrace();

      }

      }

      }

      通過 Class類的 forName(Strings)方法把自定義類TestClass加載進來,并通過 newInstance()方法把實例初始化。Class的 forName()方法還有另外一種形式:ClassforName(String s,Boolean flag,ClassLoader classloader),s表示需要加載類的名稱,flag表示在調用該函數加載類的時候是否初始化靜態(tài)區(qū),classloader表示加載該類所需的加載器。

      forName(String s)是默認通過

      ClassLoader.getCallerClassLoader()調用類加載器的,但是該方法是私有方法,我們無法調用,如果我們想使用

      ClassforName(String s,Boolean flag,ClassLoader classloader)來加載類的話,就必須要指定類加載器,可以通過如下的方式來實現:

      Tes ttest=new Test();//Test類為自定義的一個測試類;

      ClassLoader cl=test.getClass().getClassLoader();

      //獲取test的類裝載器;

      Classc=Class.forName("TestClass",true,cl);

      因為一個類要加載就必需要有加載器,這里我們是通過獲取加載Test類的加載器cl當作加載TestClass的類加載器來實現加載的。

      3 自定義類加載機制

      之前兩種類加載方式都是調用系統(tǒng)的類加載器來實現加載的,其實也可以由程序員自己定義類加載器的。利用Java提供的java.net.URLClassLoader類就可以實現,代碼如下:

      try{

      URLurl=newURL("file:/d:/test/lib/");

      URLClassLoaderurlCL=newURLClassLoader(newURL[]{url});

      Classc=urlCL.loadClass("TestClassA");

      TestClassAobject=(TestClassA)c.newInstance();object.method();

      }catch(Exceptione){e.printStackTrace();}

      通過自定義的類加載器實現了 TestClassA類的加載并調用method()方法。分析一下這個程序:首先定義URL指定類加載器從何處加載類,URL可以指向網際網絡上的任何位置,也可以指向計算機里的文件系統(tǒng)(包含JAR文件)。上述范例當中是從 file:/d:/test/lib/處尋找類;然后定義URLClassLoader來加載所需的類,最后即可使用該實例了。

      4 類加載器的階層體系

      當執(zhí)行java***.class的時候,java.exe會找到JRE,接著找到位于JRE內部的jvm.dll,這才是真正的Java虛擬機器,最后加載動態(tài)庫,激活Java虛擬機器。虛擬機器激活以后,會先做一些初始化的動作,比如說讀取系統(tǒng)參數等。一旦初始化動作完成之后,就會產生第一個類加載器―BootstrapLoader,BootstrapLoader是由 C++所撰寫而成,這個BootstrapLoader所做的初始工作中,除了一些基本的初始化動作之外,最重要的就是加載Launcher.java之中的ExtClassLoader,并設定其 Parent為null,代表其父加載器為 BootstrapLoader。然后 BootstrapLoader再要求加載 Laun- cher.java之中的AppClassLoader,并設定其 Parent為之前產生的ExtClassLoader實體。這兩個加載器都是以靜態(tài)類的形式存在的。這里要需要注意的是,Launcher$ExtClass- Loader.-class與Launcher$AppClassLoader.class都是由Boot- strapLoader所加載,所以Parent和由哪個類加載器加載沒有關系。

      猜你喜歡
      調用實例內存
      核電項目物項調用管理的應用研究
      “春夏秋冬”的內存
      當代陜西(2019年13期)2019-08-20 03:54:22
      LabWindows/CVI下基于ActiveX技術的Excel調用
      測控技術(2018年5期)2018-12-09 09:04:46
      基于系統(tǒng)調用的惡意軟件檢測技術研究
      完形填空Ⅱ
      完形填空Ⅰ
      基于內存的地理信息訪問技術
      利用RFC技術實現SAP系統(tǒng)接口通信
      上網本為什么只有1GB?
      策勒县| 云安县| 自贡市| 洪湖市| 景宁| 芦山县| 武陟县| 蓝田县| 花垣县| 阳泉市| 蒲江县| 衡山县| 思南县| 耒阳市| 平昌县| 中方县| 新河县| 洪湖市| 即墨市| 尤溪县| 萝北县| 兴义市| 通辽市| 大余县| 剑河县| 辉南县| 泰和县| 洪泽县| 丹寨县| 扎兰屯市| 察哈| 雅安市| 分宜县| 赫章县| 兴和县| 白山市| 禄劝| 峨眉山市| 合作市| 清新县| 泰宁县|