本篇內(nèi)容主要講解“什么是ClassLoader類加載器”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“什么是ClassLoader類加載器”吧!
在西城等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì) 網(wǎng)站設(shè)計(jì)制作按需定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計(jì),成都營銷網(wǎng)站建設(shè),成都外貿(mào)網(wǎng)站建設(shè)公司,西城網(wǎng)站建設(shè)費(fèi)用合理。
在Java語言中提供了一個(gè)系統(tǒng)的環(huán)境變量:CLASSPATH,這個(gè)環(huán)境屬性的作用主要是在JVM進(jìn)程啟動(dòng)時(shí)進(jìn)行類加載路徑的定義,在JVM中可以根據(jù)類加載器而后進(jìn)行指定路徑中類的加載,也就是說找到了類的加載器就意味著找到了類的來源。
ClassLoader
如果現(xiàn)在要想獲得類的加載器,那么一定要通過ClassLoader來獲取,而要想獲取ClassLoader類的對(duì)象,則必須利用Class類(反射的根源)實(shí)現(xiàn),方法:public ClassLoader getClassLoader()
當(dāng)獲取了ClassLoader后還可以獲取其父類的ClassLoader類對(duì)象: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());//獲取當(dāng)前類加載器//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)提供有一個(gè)“PlatformClassLoader”類加載器,而在JDK1.8及以前的版本中提供的加載器為“ ExtClassLoader”,因?yàn)樵贘DK的安裝目錄中提供了一個(gè)ext的目錄,開發(fā)者可以將*.jar文件拷貝到此目錄中,這樣就可以直接執(zhí)行了,但是這樣的處理開發(fā)并不安全,最初的時(shí)候也是不提倡使用的,所以從JDK1.9開始將其徹底廢除了,同時(shí)為了與系統(tǒng)類加載器和應(yīng)用類加載器之間保持設(shè)計(jì)的平衡,提供有平臺(tái)類加載器。
當(dāng)你獲得了類加載器后就可以利用類加載器來實(shí)現(xiàn)類的反射加載處理:protected Class> findClass(String name) throws ClassNotFoundException
清楚了類加載器的功能后就可以根據(jù)自身的需求來實(shí)現(xiàn)自定義的類加載器,但是千萬要記住一點(diǎn):自定義的類加載器其加載的順序是在所有系統(tǒng)類加載器的最后。系統(tǒng)類中的類加載器都是根據(jù)CLASSPATH路徑進(jìn)行加載的,而如果有了自定義的類加載器,就可以由開發(fā)者任意指定類的加載位置。
自定義類加載器
1、隨意編寫一個(gè)程序類,并且將這個(gè)類保存在磁盤上。
public class Message {public void send(){ System.out.println("www.mldn.cn"); } }
2、將此類直接拷貝到系統(tǒng)磁盤上(非項(xiàng)目路徑)進(jìn)行編譯處理,并且不打包:javac Message.java,此時(shí)并沒有進(jìn)行打包處理,所以這個(gè)類無法通過CLASSPATH正常加載。javac /Users/david/Documents/mydir/Message.java
3、自定義一個(gè)類加載器,并且繼承自ClassLoader類。在ClassLoader類中提供有一個(gè)字節(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";/** * 進(jìn)行指定類的加載 * * @param className 類的完整名稱“包.類” * @return 返回一個(gè)指定類的Class對(duì)象 * @throws Exception 如果類文件不存在,則無法加載 */public Class> loadData(String className) throws Exception { byte[] data = loadClassData();//讀取二進(jìn)制數(shù)據(jù)文件if (data != null) { //讀取到了return super.defineClass(className, data, 0, data.length); }return null; }private byte[] loadClassData() throws Exception {//通過文件進(jìn)行類的加載InputStream input = null;ByteArrayOutputStream bos = null; //將數(shù)據(jù)加載到內(nèi)存之中byte data [] = null;try { bos = new ByteArrayOutputStream(); //實(shí)例化內(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、編寫測(cè)試類實(shí)現(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(); //實(shí)例化自定義類加載器Class> cls=classLoader.loadData("cn.mldn.util.Message");Object obj = cls.getDeclaredConstructor().newInstance();Method method = cls.getDeclaredMethod("send");method.invoke(obj); } }
如果在以后結(jié)合網(wǎng)絡(luò)程序開發(fā)的話,就可以通過一個(gè)遠(yuǎn)程的服務(wù)器來確定一個(gè)類的功能。
應(yīng)用項(xiàng)目
5、觀察當(dāng)前的Message類的加載器的情況
public class JavaAPIDemo { public static void main(String[] args)throws Exception{ MLDNClassLoader classLoader = new MLDNClassLoader();//實(shí)例化自定義類加載器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)在定義了一個(gè)類:java.lang.String,并且利用了自定義的類加載器進(jìn)行加載處理,這個(gè)類將不會(huì)被加載,Java之中針對(duì)于類加載器提供有雙親加載機(jī)制,如果現(xiàn)在要加載的程序類是由系統(tǒng)提供的類則會(huì)由系統(tǒng)類加載器進(jìn)行加載,在開發(fā)者定義的類與系統(tǒng)類名稱相同,那么為了保證系統(tǒng)的安全性絕對(duì)不會(huì)加載。
到此,相信大家對(duì)“什么是ClassLoader類加載器”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!