1. 程式人生 > >java基礎-類載入器:實現一個類載入器

java基礎-類載入器:實現一個類載入器

    1,如何識別class檔案?
    通過MD5加密演算法
    2,載入:
    啟動類載入器:Bootstrap Classloade>載入 jre/lib/rt.jar   :主要有Object,String等類
    擴充套件類載入器:ExtClassLoader>載入jre/lib/ext/*  jar 主要是JAVA_HOME/jre/lib/ext 路徑下的jar包

應用類載入器:AppClassLoader>載入classpath路徑下所有的jar和目錄 載入自己所寫的類

      通過類載入器:
            class

loadclass方法:負責以雙親委託的方式去載入類
findclass方法:根據類的包路徑找到class檔案
defineclass:負責從位元組碼中載入class物件,然後class物件通過反射機制生成物件。
findclass次數<=loadclass次數
如何實現一個類載入器?
不能夠破壞雙親委派模型
重寫一個方法: findclass() //其他兩個不能重寫。重寫loadclass會破壞雙親委派模型。defineclass只有包許可權,只能原始碼呼叫。

import java.io.*;

/**
* @Created with IntelliJ IDEA
* @Description:
* @Package: PACKAGE_NAME
* @User: FLy
* @Date: 2018/11/21
* @Time: 10:20
*/
class MyClassLoader extends ClassLoader{

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        //TODO Auto-generated method stub
        String Dir="D:";//使用者自定義路徑進行拼接
        String classPath=Dir+File.separatorChar+name.replace('.',File.separatorChar)+".class";
        File file= new File(classPath);
        byte[] buff=null;
        InputStream in;
        try{
            in=new FileInputStream(file);
            buff=new byte[in.available()];
            in.read(buff);
            in.close();
            Class<?> c=defineClass(name,buff,0,buff.length);
            return c;
        }catch (FileNotFoundException e){
            //TODO Auto-generated catch block
            e.printStackTrace();
        }catch(IOException e) {
            //TODO Auto-generted catch block
            e.printStackTrace();
        }
        return super.findClass(classPath);
    }
}

雙親委派模型的好處:
1.
安全性:避免使用者自己編寫的類動態替換java中的一些核心類。如果不採用雙親委派模型的載入方式進行類的載入工作,那我們就可以隨便使用自己定義的類來動態的替換java核心API中定義的類。 而雙親委派模型的這種載入方式就可以避免這種情況,因為String類在啟動時就被啟動類載入器進行載入。
2.
避免類的重複載入;因為JVM判定兩個類是否是同一個類,不僅僅根據類名是否相同進行判定,還需要判斷載入該類的載入器是否是同一個載入器。相同的class檔案被不同的類載入器進行載入得到的結果就是不同的類。
3.
JAVA類隨著它的類載入器一起具備了一種帶有優先順序的層次關係。例如Java。lang.Object。它存在於rt.jar中,無論哪一個類載入器要載入這個類,最終都委派給處於模型頂端的Bootstrap ClassLoader進行載入,因此Object類在程式的各種類載入器環境中都是同一個類。相反如果沒有雙親委派模型,而是由各個類載入器自行載入的話,如果使用者編寫了一個java.lang.Object的同名類並放在classPath中,那麼系統中將會出現多個不同的Object類,程式將混亂。因此。如果開發者嘗試編寫一個與rt.jar類庫中重名的java類,可以正常編譯,但無法被載入執行

在這裡插入圖片描述