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

首頁 > 學院 > 開發設計 > 正文

Java類加載原理及自定義類加載器

2019-11-17 04:00:17
字體:
來源:轉載
供稿:網友
     java和其他語言不同的是,Java是運行于Java虛擬機(JVM)。這就意味著編譯后的代碼是以
一種和平臺無關的格式保存的,而不是某種特定的機器上運行的格式。這種格式和傳統的可
執行代碼格式有很多重要的區別。具體來說,不同于C或者C++程序,Java程序不是一個獨
立的可執行文件,而是由很多分開的類文件組成,每個類文件對應一個Java類。 另外,這
些類文件并不是馬上加載到內存,而是當程序需要的時候才加載。 類加載器就是Java虛擬
機中用來把類加載到內存的工具。而且,Java類加載器也是用Java實現的。這樣你就不需要
對Java虛擬機有深入的理解就可以很容易創建自己的類加載器了。
     為什么要創建類加載器?
      既然Java虛擬機已經有了類加載器,我們還要自己創建其他的嗎?問得好。默認的類加載器
只知道如何從本地系統加載類。當你的程序完全在本機編譯的話,默認的類加載器一般都工
作的很好。但是Java中最激動人心的地方之一就是很容易的從網絡上而不只是本地加載類。
舉個例子,瀏覽器可以通過自定義的類加載器加載類。 還有
很多加載類的方式。除了簡單的從本地或者網絡外,你還可以通過自定義Java中最激動人心
的地方之一:
* 執行非信任代碼前自動驗證數字簽名
* 根據用戶提供的密碼解密代碼
* 根據用戶的需要動態的創建類
你關心的任何東西都能方便的以字節碼的形式集成到你的應用中
自定義類加載器的例子
如果你已經使用過JDK(Java軟件開發包)中的appletviewer(小應用程序瀏覽器)或者其他
Java嵌入式瀏覽器,你就已經使用了自定義類加載器了。Sun剛剛發布Java語言的時候,最
令人興奮的一件事就是觀看Java如何執行從遠程網站下載的代碼。執行從遠程站點通過HTT
P連接傳送來的字節碼看起來有點不可思議。之所以能夠工作,因為Java有安裝自定義類加
載器的能力。小應用程序瀏覽器包含了一個類加載器,這個類加載器不從本地找Java類,而
是訪問遠程服務器,通過HTTP加載原始字節碼文件,然后在Java虛擬機中轉化為Java類。當
然類加載器還做了其他的很多事情:他們阻止不安全的Java類,而且保持不同頁面上的不同
小程序不會互相干擾。Luke Gorrie寫的一個包Echidna是一個開放的Java軟件包,他允許在
一個Java虛擬機中安全的運行多個Java應用程序。它通過使用自定義類加載器給每個應用程
序一份類文件的拷貝來阻止應用程序之間的干擾。


java類加載器 :

java中默認有三種類加載器:引導類加載器,擴展類加載器,系統類加載器(也叫應用類加載器)

類加載器是Java最強大的特征之一。但是開發者常常忘記類加載組件。類加載器是在運行時負責尋找和加載類文件的類。Java允許使用不同的類加載器,甚至自定義的類加載器。

Java 程序包含很多類文件,每一個都與單個Java類相對應,這些類文件不像靜態C程序,一次性加載入內存,它們隨時需要隨時加載。這就是類加載器與眾不同的地 方。它從源文件(通常是.class 或 .jar文件)獲得不依賴平臺的字節碼,然后將它們加載到JVM內存空間,所以它們能被解釋和執行。默認狀態下,應用程序的每個類由 java.lang.ClassLoader加載。因為它可以被繼承,所以可以自由地加強其功能。


自定義類加載器

import java.io.*;    
import java.net.*;    
import java.util.*;    
import java.lang.reflect.Method;    
   
public class CustomClassLoader extends URLClassLoader {    
    PRivate FileInputStream input = null;  //文件輸入流    
    private ByteArrayOutputStream out = null;  //字節數組輸出流    
    private String[] url = null;  //類文件加載路徑    
    private byte[] data = null; //類文件字節碼    
    private String extensionalName = ""; //類文件擴展名    
   
    public CustomClassLoader(URL[] urls) throws Exception{    
        super(urls);    
        this.url = new String[urls.length];    
        for (int i = 0; i < urls.length; i++) {    
             this.url[i] = urls[i].toURI().toString();    
        }    
    }    
        
    /*   
     * 解析URL    
     */   
    private void setFilePath() {    
        for (int i = 0; i < this.url.length; i++) {    
            if (this.url[i].substring(0,4).toLowerCase().equals("file") == true) {    
                this.url[i] = this.url[i].substring(5);    
            }    
        }    
    }    
   
    /*   
     * 獲得指定類名(包名+類名)文件的字節碼   
     * @name name String   
     * @return byte[]   
     */   
    private byte[] getFileData(String name) {    
        try {    
            this.setFilePath();    
            for (String url : this.url) {    
                String fileName = url + name.replace('.', '/').concat(".") +    
                                  this.getExtensionalName();    
                input = new FileInputStream(new File(fileName));    
                if (input != null) {    
                    break;    
                }    
            }              
                
            out = new ByteArrayOutputStream();    
            data = new byte[1024];    
            int len = -1;    
            while ((len = input.read(data)) != -1) {    
                out.write(data, 0, len);    
            }    
            data = out.toByteArray();    
        } catch (Exception e) {    
            e.printStackTrace();    
        } finally {    
            try {    
                if (input != null)    
                    input.close();    
                if (out != null)    
                    out.close();    
                return data;    
            } catch (Exception e) {    
                e.printStackTrace();    
                return null;    
            }    
        }    
    }    
   
    /*   
     * 根據指定類名查找類文件   
     * @param name String   
     * @return Class   
     */   
    protected Class findClassByName(String name) {    
        try {    
            byte[] data = this.getFileData(name);    
            if (data == null) {    
                return null;    
            }    
            return this.defineClass(name, data, 0, data.length);    
        } catch (Exception e) {    
            e.printStackTrace();    
            return null;    
        }    
   
    }    
   
    /*   
     * 重寫loadClass()方法   
     * @param name String   
     * @return Class   
     */   
    public Class loadClass(String name) {    
        Class c = null;            
        try {    
            c = super.loadClass(name);            
        } catch (ClassNotFoundException e) {    
            e.printStackTrace();    
        } finally {    
            if (c == null) //父類默認方法沒有加載到指定類時,使用自定義方法查找    
                c = this.findClassByName(name);    
            return c;    
        }    
    }    
   
    public String getExtensionalName() {    
        return extensionalName;    
    }    
   
    public void setExtensionalName(String extensionalName) {    
        this.extensionalName = extensionalName;    
    }    
   
   
   
    public static void main(String[] args) throws Exception {    
        URL[] url = new URL[] {new URL("file:e:/")}; //添加你想要加載類的路徑    
                                                     //網絡或本地均可    
        CustomClassLoader csl = new CustomClassLoader(url);    
        csl.setExtensionalName("rs");    
        Class c1 = csl.loadClass("com.demo");    
        Object obj = c1.newInstance();    
        Method method = c1.getMethod("printText", null);    
        method.invoke(obj, null);    
    }    
}   
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 塘沽区| 赞皇县| 印江| 松阳县| 阿坝| 彭州市| 靖远县| 吴忠市| 建湖县| 莱州市| 无棣县| 丹巴县| 林周县| 玉田县| 双峰县| 兴安盟| 壶关县| 将乐县| 北京市| 阿尔山市| 汾西县| 黄浦区| 安图县| 上蔡县| 陕西省| 盈江县| 当阳市| 桂东县| 托克逊县| 班戈县| 南木林县| 两当县| 赤城县| 武宁县| 阿合奇县| 绥宁县| 平安县| 侯马市| 陆良县| 阿勒泰市| 克拉玛依市|