java 類加載與自定義類加載器詳解
類加載
所有類加載器,都是ClassLoader的子類。
類加載器永遠以.class運行的目錄為準。
讀取classpath根目錄下的文件有以下幾種方式:
1 在Java項目中可以通過以下方式獲取classspath下的文件:
public void abc(){ //每一種讀取方法,使用某個類獲取Appclassloader ClassLoader cl = ReadFile.class.getClassLoader(); URL url = cl.getResource("a.txt"); System.err.println("url1 is:"+url.getPath()); //第二種方式,直接使用ClassLoader URL url2 = ClassLoader.getSystemResource("a.txt"); System.err.println("url2 is:"+url2.getPath()); }
在Tomcat中tomcat又聲明了兩個類載器:
StandardClassLoader– 加載tomcat/lib/*.jar - serlvetapi.jar
Webappclassloader /加載 tomcat/webapps/project/web-inf/lib/*.jar && web-inf/classes/*.class
在任何的項目中,獲取類的加載器都應(yīng)該使用以下方式:
SomeClass(你寫的).class.getClassLoader().getResource ;獲取到這個類的類加載器
在java項目中是:AppClassLoader
在Web項目中:WebAppClassLoader
測試父類加載器:
public class OneServlet extends HttpServlet { @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ClassLoader loader = OneServlet.class.getClassLoader();//WebAppClassLoader int index=1; while(loader!=null){ System.err.println((index++)+"類加載器是:"+loader.getClass()); loader=loader.getParent();//獲取父類加載器 } } }
運行的結(jié)果:
1類加載器是:class org.apache.catalina.loader.WebappClassLoader 2類加載器是:class org.apache.catalina.loader.StandardClassLoader 3類加載器是:class sun.misc.Launcher$AppClassLoader 4類加載器是:class sun.misc.Launcher$ExtClassLoader
自定義類加載器
JDK以哪一個類加載器讀取A類的字節(jié)碼,則A類就是被哪一個類加載器加載 的。
一個同名的類,是否可以相互轉(zhuǎn)換,要看是否是在同個類加載器中。
package cn.hx.demo; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.net.URL; public class MyClassLoader2 extends ClassLoader { /** * name:cn.itcast.demo.Person * 根據(jù)包名找到.class文件 * cn.itcast.demo.person = > cn/itcast/demo/Person.class */ public Class<?> findClass(String name ) throws ClassNotFoundException { String classNameWithPackage=name; Class<?> cls = null; try { //先將 name = name.replace(".","/"); name +=".class"; //確定目錄 URL url = MyClassLoader2.class.getClassLoader().getResource(name); System.err.println(">>:"+url.getPath()); File file = new File(url.getPath()); InputStream in = new FileInputStream(file); //讀取這個.class文件的字節(jié)碼 byte[] b = new byte[in.available()];//直接聲明這個字節(jié)大小為這個文件的大小 int len = in.read(b);//len=621 System.err.println(len); /** * 第一個參數(shù)是類名 */ cls = defineClass(classNameWithPackage,b,0,len); } catch (Exception e) { e.printStackTrace(); } return cls; } }
測試類自定義類加載器
public class ClassLoaderDemo { public static void main(String[] args) throws Exception { MyClassLoader2 mc = new MyClassLoader2(); Class cls = mc.findClass("cn.itcast.demo.Person"); Object o = cls.newInstance(); System.err.println("toString:"+o+","+o.getClass().getClassLoader()); //直接使用peron是 AppClassLoader System.err.println(">>:"+Person.class.getClassLoader()); //由于o是由mc加載的。而Person是由App加載的,所有不可以轉(zhuǎn)換=來自于兩個不同的加載器 //Person p = (Person) o;//類型轉(zhuǎn)換錯誤ClassCastException //System.err.println(p); } }
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
相關(guān)文章
解讀@NoArgsConstructor,@AllArgsConstructor,@RequiredArgsConstr
這篇文章主要介紹了解讀@NoArgsConstructor,@AllArgsConstructor,@RequiredArgsConstructor的區(qū)別及在springboot常用地方,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12Java API方式調(diào)用Kafka各種協(xié)議的方法
本篇文章主要介紹了Java API方式調(diào)用Kafka各種協(xié)議的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09java數(shù)組實現(xiàn)隊列及環(huán)形隊列實現(xiàn)過程解析
這篇文章主要介紹了java數(shù)組實現(xiàn)隊列及環(huán)形隊列實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-10-10Spring實戰(zhàn)之調(diào)用實例工廠方法創(chuàng)建Bean操作示例
這篇文章主要介紹了Spring實戰(zhàn)之調(diào)用實例工廠方法創(chuàng)建Bean操作,結(jié)合實例形式分析了實例工廠方法創(chuàng)建Bean相關(guān)配置、實現(xiàn)方法及操作注意事項,需要的朋友可以參考下2019-11-11JAVA基于Arrays.sort()實現(xiàn)數(shù)組升序和降序
這篇文章主要介紹了JAVA基于Arrays.sort()實現(xiàn)數(shù)組升序和降序,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06Springboot整合Mybatis傳值的常用方式總結(jié)
今天給大家?guī)淼氖顷P(guān)于Springboot的相關(guān)知識,文章圍繞著Springboot整合Mybatis傳值的常用方式展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下2021-06-06java使用Socket實現(xiàn)SMTP協(xié)議發(fā)送郵件
這篇文章主要為大家詳細介紹了java使用Socket實現(xiàn)SMTP協(xié)議發(fā)送郵件的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-05-05