溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

什么是ClassLoader類加載器

發(fā)布時間:2021-07-08 17:55:06 來源:億速云 閱讀:161 作者:chen 欄目:編程語言

本篇內(nèi)容主要講解“什么是ClassLoader類加載器”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“什么是ClassLoader類加載器”吧!

ClassLoader類加載器

在Java語言中提供了一個系統(tǒng)的環(huán)境變量:CLASSPATH,這個環(huán)境屬性的作用主要是在JVM進程啟動時進行類加載路徑的定義,在JVM中可以根據(jù)類加載器而后進行指定路徑中類的加載,也就是說找到了類的加載器就意味著找到了類的來源。

什么是ClassLoader類加載器
ClassLoader

系統(tǒng)類加載器

如果現(xiàn)在要想獲得類的加載器,那么一定要通過ClassLoader來獲取,而要想獲取ClassLoader類的對象,則必須利用Class類(反射的根源)實現(xiàn),方法:
public ClassLoader getClassLoader()
當獲取了ClassLoader后還可以獲取其父類的ClassLoader類對象:
public final ClassLoader getParent()
范例:觀察類加載器

class Message{}
public class JavaAPIDemo {
    public static void main(String[] args)throws Exception{
        Class<?> clazz=Message.class;System.out.println(clazz.getClassLoader());//獲取當前類加載器//1.8:sun.misc.Launcher$AppClassLoader@6659c656//1.9+:jdk.internal.loader.ClassLoaders$AppClassLoader@4f8e5cdeSystem.out.println(clazz.getClassLoader().getParent());//獲取父類加載器//1.8:sun.misc.Launcher$ExtClassLoader@60e53b93//1.9+:jdk.internal.loader.ClassLoaders$PlatformClassLoader@5d3411dSystem.out.println(clazz.getClassLoader().getParent().getParent());//獲取祖父類加載器 ,null}
}

從JDK1.8之后的版本(JDK1.9,JDK1.10)提供有一個“PlatformClassLoader”類加載器,而在JDK1.8及以前的版本中提供的加載器為“ ExtClassLoader”,因為在JDK的安裝目錄中提供了一個ext的目錄,開發(fā)者可以將*.jar文件拷貝到此目錄中,這樣就可以直接執(zhí)行了,但是這樣的處理開發(fā)并不安全,最初的時候也是不提倡使用的,所以從JDK1.9開始將其徹底廢除了,同時為了與系統(tǒng)類加載器和應用類加載器之間保持設計的平衡,提供有平臺類加載器。

當你獲得了類加載器后就可以利用類加載器來實現(xiàn)類的反射加載處理:
protected Class<?> findClass(String name) throws ClassNotFoundException

自定義類加載器

清楚了類加載器的功能后就可以根據(jù)自身的需求來實現(xiàn)自定義的類加載器,但是千萬要記住一點:自定義的類加載器其加載的順序是在所有系統(tǒng)類加載器的最后。系統(tǒng)類中的類加載器都是根據(jù)CLASSPATH路徑進行加載的,而如果有了自定義的類加載器,就可以由開發(fā)者任意指定類的加載位置。

什么是ClassLoader類加載器
自定義類加載器

1、隨意編寫一個程序類,并且將這個類保存在磁盤上。

public class Message {public void send(){
        System.out.println("www.mldn.cn");
    }
}

2、將此類直接拷貝到系統(tǒng)磁盤上(非項目路徑)進行編譯處理,并且不打包:javac Message.java,此時并沒有進行打包處理,所以這個類無法通過CLASSPATH正常加載。
javac /Users/david/Documents/mydir/Message.java
3、自定義一個類加載器,并且繼承自ClassLoader類。在ClassLoader類中提供有一個字節(jié)轉(zhuǎn)換為類結(jié)構(gòu)的方法:

定義類:
protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError

import java.io.*;
public class MLDNClassLoader extends ClassLoader {private static final String MESSAGE_CLASS_PATH = "D:" + File.separator + "Message.class";/**
     * 進行指定類的加載
     *
     * @param className 類的完整名稱“包.類”
     * @return 返回一個指定類的Class對象
     * @throws Exception 如果類文件不存在,則無法加載
     */public Class<?> loadData(String className) throws Exception {
        byte[] data = loadClassData();//讀取二進制數(shù)據(jù)文件if (data != null) {  //讀取到了return super.defineClass(className, data, 0, data.length); 
        }return null;
    }private byte[] loadClassData() throws Exception {//通過文件進行類的加載InputStream input = null;ByteArrayOutputStream bos = null;  //將數(shù)據(jù)加載到內(nèi)存之中byte data [] = null;try { 
            bos = new ByteArrayOutputStream();  //實例化內(nèi)存流input = new FileInputStream(new File(MESSAGE_CLASS_PATH));  //文件加載流input.transferTo(bos);  //讀取數(shù)據(jù)data = bos.toByteArray();  //將所有讀取到的字節(jié)數(shù)取出} catch (Exception e) {
            e.printStackTrace();
        } finally {if (input != null) {
                input.close();
            }if (bos != null) {
                bos.close();
            }
        }return data;
    }
}

4、編寫測試類實現(xiàn)類加載控制。

import  java.lang.reflect.Method;import cn.mldn.util.MLDNClassLoader;public class JavaAPIDemo {public static void main(String[] args)throws Exception{
        MLDNClassLoader classLoader = new MLDNClassLoader();  //實例化自定義類加載器Class<?> cls=classLoader.loadData("cn.mldn.util.Message");Object obj = cls.getDeclaredConstructor().newInstance();Method method = cls.getDeclaredMethod("send");method.invoke(obj);
    }
}

如果在以后結(jié)合網(wǎng)絡程序開發(fā)的話,就可以通過一個遠程的服務器來確定一個類的功能。

應用項目

5、觀察當前的Message類的加載器的情況

public class JavaAPIDemo {
    public static void main(String[] args)throws Exception{
        MLDNClassLoader classLoader = new MLDNClassLoader();//實例化自定義類加載器Class<?> clazz=classLoader.loadData("cn.mldn.util.Message");System.out.println(cls.getClassLoader());  //cn.mldn.util.MLDNClassLoader@6979e8cbSystem.out.println(cls.getClassLoader().getParent()); //jdk.internal.loader.ClassLoaders$AppClassLoader@6659c656System.out.println(cls.getClassLoader().getParent().getParent());  //jdk.internal.loader.ClassLoaders$PlatformClassLoader@763d9750}
}

如果現(xiàn)在定義了一個類:java.lang.String,并且利用了自定義的類加載器進行加載處理,這個類將不會被加載,Java之中針對于類加載器提供有雙親加載機制,如果現(xiàn)在要加載的程序類是由系統(tǒng)提供的類則會由系統(tǒng)類加載器進行加載,在開發(fā)者定義的類與系統(tǒng)類名稱相同,那么為了保證系統(tǒng)的安全性絕對不會加載。

到此,相信大家對“什么是ClassLoader類加載器”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關內(nèi)容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI