国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
全面解析Java類加載器

深入理解和探究Java類加載機(jī)制----

1.java.lang.ClassLoader類介紹

java.lang.ClassLoader類的基本職責(zé)就是根據(jù)一個(gè)指定的類的名稱,找到或者生成其對(duì)應(yīng)的字節(jié)代碼,然后從這些字節(jié)代碼中定義出一個(gè)Java 類,即 java.lang.Class類的一個(gè)實(shí)例。

ClassLoader提供了一系列的方法,比較重要的方法如:

 

 

2.JVM中類加載器的樹狀層次結(jié)構(gòu)

Java 中的類加載器大致可以分成兩類,一類是系統(tǒng)提供的,另外一類則是由 Java 應(yīng)用開發(fā)人員編寫的。 

引導(dǎo)類加載器(bootstrap class loader):

它用來(lái)加載 Java 的核心庫(kù)(jre/lib/rt.jar),是用原生C++代碼來(lái)實(shí)現(xiàn)的,并不繼承自java.lang.ClassLoader。

加載擴(kuò)展類和應(yīng)用程序類加載器,并指定他們的父類加載器,在java中獲取不到。 

擴(kuò)展類加載器(extensions class loader):

它用來(lái)加載 Java 的擴(kuò)展庫(kù)(jre/ext/*.jar)。Java 虛擬機(jī)的實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫(kù)目錄。該類加載器在此目錄里面查找并加載 Java 類。 

系統(tǒng)類加載器(system class loader):

它根據(jù) Java 應(yīng)用的類路徑(CLASSPATH)來(lái)加載 Java 類。一般來(lái)說(shuō),Java 應(yīng)用的類都是由它來(lái)完成加載的??梢酝ㄟ^(guò) ClassLoader.getSystemClassLoader()來(lái)獲取它。

自定義類加載器(custom class loader):

除了系統(tǒng)提供的類加載器以外,開發(fā)人員可以通過(guò)繼承 java.lang.ClassLoader類的方式實(shí)現(xiàn)自己的類加載器,以滿足一些特殊的需求。

 

以下測(cè)試代碼可以證明此層次結(jié)構(gòu):

public class testClassLoader {    @Test    public void test(){        //application class loader        System.out.println(ClassLoader.getSystemClassLoader());        //extensions class loader        System.out.println(ClassLoader.getSystemClassLoader().getParent());        //bootstrap class loader        System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());    }}

輸出為:

 

可以看出ClassLoader類是由AppClassLoader加載的。他的父親是ExtClassLoader,ExtClassLoader的父親無(wú)法獲取是因?yàn)樗怯肅++實(shí)現(xiàn)的。

 

3.雙親委派機(jī)制

  某個(gè)特定的類加載器在接到加載類的請(qǐng)求時(shí),首先將加載任務(wù)委托交給父類加載器,父類加載器又將加載任務(wù)向上委托,直到最父類加載器,如果最父類加載器可以完成類加載任務(wù),就成功返回,如果不行就向下傳遞委托任務(wù),由其子類加載器進(jìn)行加載。

雙親委派機(jī)制的好處:

  保證java核心庫(kù)的安全性(例如:如果用戶自己寫了一個(gè)java.lang.String類就會(huì)因?yàn)殡p親委派機(jī)制不能被加載,不會(huì)破壞原生的String類的加載)

代理模式

  與雙親委派機(jī)制相反,代理模式是先自己嘗試加載,如果無(wú)法加載則向上傳遞。tomcat就是代理模式。

 

4.自定義類加載器

public class MyClassLoader extends ClassLoader{    private String rootPath;        public MyClassLoader(String rootPath){        this.rootPath = rootPath;    }        @Override    protected Class<?> findClass(String name) throws ClassNotFoundException {        //check if the class have been loaded        Class<?> c = findLoadedClass(name);                if(c!=null){            return c;        }        //load the class        byte[] classData = getClassData(name);        if(classData==null){            throw new ClassNotFoundException();        }        else{            c = defineClass(name,classData, 0, classData.length);            return c;        }        }        private byte[] getClassData(String className){        String path = rootPath+"/"+className.replace('.', '/')+".class";                InputStream is = null;        ByteArrayOutputStream bos = null;        try {            is = new FileInputStream(path);            bos = new ByteArrayOutputStream();            byte[] buffer = new byte[1024];            int temp = 0;            while((temp = is.read(buffer))!=-1){                bos.write(buffer,0,temp);            }            return bos.toByteArray();        } catch (Exception e) {            e.printStackTrace();        }finally{            try {                is.close();                bos.close();            } catch (Exception e) {                e.printStackTrace();            }                    }                return null;            }    }

測(cè)試自定義的類加載器

創(chuàng)建一個(gè)測(cè)試類HelloWorld

package testOthers;public class HelloWorld {}

在D盤根目錄創(chuàng)建一個(gè)testOthers文件夾,編譯HelloWorld.java,將得到的class文件放到testOthers文件夾下。

利用如下代碼進(jìn)行測(cè)試

public class testMyClassLoader {    @Test    public void test() throws Exception{        MyClassLoader loader = new MyClassLoader("D:");        Class<?> c = loader.loadClass("testOthers.HelloWorld");        System.out.println(c.getClassLoader());    }}

輸出:

 

說(shuō)明HelloWorld類是被我們的自定義類加載器MyClassLoader加載的

 

5.類加載過(guò)程詳解

JVM將類加載過(guò)程分為三個(gè)步驟:裝載(Load),鏈接(Link)和初始化(Initialize)

1) 裝載

  查找并加載類的二進(jìn)制數(shù)據(jù);

2)鏈接

  驗(yàn)證:確保被加載類信息符合JVM規(guī)范、沒(méi)有安全方面的問(wèn)題。

  準(zhǔn)備:為類的靜態(tài)變量分配內(nèi)存,并將其初始化為默認(rèn)值。

  解析:把虛擬機(jī)常量池中的符號(hào)引用轉(zhuǎn)換為直接引用。

3)初始化

  為類的靜態(tài)變量賦予正確的初始值。

ps:解析部分需要說(shuō)明一下,Java 中,虛擬機(jī)會(huì)為每個(gè)加載的類維護(hù)一個(gè)常量池【不同于字符串常量池,這個(gè)常量池只是該類的字面值(例如類名、方法名)和符號(hào)引用的有序集合。 而字符串常量池,是整個(gè)JVM共享的】這些符號(hào)(如int a = 5;中的a)就是符號(hào)引用,而解析過(guò)程就是把它轉(zhuǎn)換成指向堆中的對(duì)象地址的相對(duì)地址。

 

類的初始化步驟:

1)如果這個(gè)類還沒(méi)有被加載和鏈接,那先進(jìn)行加載和鏈接

2)假如這個(gè)類存在直接父類,并且這個(gè)類還沒(méi)有被初始化(注意:在一個(gè)類加載器中,類只能初始化一次),那就初始化直接的父類(不適用于接口)

3)如果類中存在static標(biāo)識(shí)的塊,那就依次執(zhí)行這些初始化語(yǔ)句。

 

 

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
深入理解JVM類加載器
解密Java虛擬機(jī)如何加載一個(gè)Class文件
超詳細(xì)java類加載器學(xué)習(xí)總結(jié)
JVM --- 結(jié)構(gòu)體系
classloader加載class文件的原理和機(jī)制
類加載器的作用
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服