您好,登錄后才能下訂單哦!
本篇內容主要講解“什么是ClassLoader類加載器”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“什么是ClassLoader類加載器”吧!
在Java語言中提供了一個系統的環境變量:CLASSPATH,這個環境屬性的作用主要是在JVM進程啟動時進行類加載路徑的定義,在JVM中可以根據類加載器而后進行指定路徑中類的加載,也就是說找到了類的加載器就意味著找到了類的來源。
ClassLoader
如果現在要想獲得類的加載器,那么一定要通過ClassLoader來獲取,而要想獲取ClassLoader類的對象,則必須利用Class類(反射的根源)實現,方法:
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的目錄,開發者可以將*.jar文件拷貝到此目錄中,這樣就可以直接執行了,但是這樣的處理開發并不安全,最初的時候也是不提倡使用的,所以從JDK1.9開始將其徹底廢除了,同時為了與系統類加載器和應用類加載器之間保持設計的平衡,提供有平臺類加載器。
當你獲得了類加載器后就可以利用類加載器來實現類的反射加載處理:
protected Class<?> findClass(String name) throws ClassNotFoundException
清楚了類加載器的功能后就可以根據自身的需求來實現自定義的類加載器,但是千萬要記住一點:自定義的類加載器其加載的順序是在所有系統類加載器的最后。系統類中的類加載器都是根據CLASSPATH路徑進行加載的,而如果有了自定義的類加載器,就可以由開發者任意指定類的加載位置。
自定義類加載器
1、隨意編寫一個程序類,并且將這個類保存在磁盤上。
public class Message {public void send(){ System.out.println("www.mldn.cn"); } }
2、將此類直接拷貝到系統磁盤上(非項目路徑)進行編譯處理,并且不打包:javac Message.java,此時并沒有進行打包處理,所以這個類無法通過CLASSPATH正常加載。
javac /Users/david/Documents/mydir/Message.java
3、自定義一個類加載器,并且繼承自ClassLoader類。在ClassLoader類中提供有一個字節轉換為類結構的方法:
定義類:
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();//讀取二進制數據文件if (data != null) { //讀取到了return super.defineClass(className, data, 0, data.length); }return null; }private byte[] loadClassData() throws Exception {//通過文件進行類的加載InputStream input = null;ByteArrayOutputStream bos = null; //將數據加載到內存之中byte data [] = null;try { bos = new ByteArrayOutputStream(); //實例化內存流input = new FileInputStream(new File(MESSAGE_CLASS_PATH)); //文件加載流input.transferTo(bos); //讀取數據data = bos.toByteArray(); //將所有讀取到的字節數取出} catch (Exception e) { e.printStackTrace(); } finally {if (input != null) { input.close(); }if (bos != null) { bos.close(); } }return data; } }
4、編寫測試類實現類加載控制。
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); } }
如果在以后結合網絡程序開發的話,就可以通過一個遠程的服務器來確定一個類的功能。
應用項目
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} }
如果現在定義了一個類:java.lang.String,并且利用了自定義的類加載器進行加載處理,這個類將不會被加載,Java之中針對于類加載器提供有雙親加載機制,如果現在要加載的程序類是由系統提供的類則會由系統類加載器進行加載,在開發者定義的類與系統類名稱相同,那么為了保證系統的安全性絕對不會加載。
到此,相信大家對“什么是ClassLoader類加載器”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。