java 類加載與自定義類加載器詳解
類加載
所有類加載器,都是ClassLoader的子類。
類加載器永遠(yuǎn)以.class運(yùn)行的目錄為準(zhǔn)。
讀取classpath根目錄下的文件有以下幾種方式:
1 在Java項(xiàng)目中可以通過以下方式獲取classspath下的文件:
public void abc(){
//每一種讀取方法,使用某個(gè)類獲取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又聲明了兩個(gè)類載器:
StandardClassLoader– 加載tomcat/lib/*.jar - serlvetapi.jar
Webappclassloader /加載 tomcat/webapps/project/web-inf/lib/*.jar && web-inf/classes/*.class
在任何的項(xiàng)目中,獲取類的加載器都應(yīng)該使用以下方式:
SomeClass(你寫的).class.getClassLoader().getResource ;獲取到這個(gè)類的類加載器
在java項(xiàng)目中是:AppClassLoader
在Web項(xiàng)目中:WebAppClassLoader

測(cè)試父類加載器:
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();//獲取父類加載器
}
}
}
運(yùn)行的結(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以哪一個(gè)類加載器讀取A類的字節(jié)碼,則A類就是被哪一個(gè)類加載器加載 的。
一個(gè)同名的類,是否可以相互轉(zhuǎn)換,要看是否是在同個(gè)類加載器中。
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);
//讀取這個(gè).class文件的字節(jié)碼
byte[] b = new byte[in.available()];//直接聲明這個(gè)字節(jié)大小為這個(gè)文件的大小
int len = in.read(b);//len=621
System.err.println(len);
/**
* 第一個(gè)參數(shù)是類名
*/
cls = defineClass(classNameWithPackage,b,0,len);
} catch (Exception e) {
e.printStackTrace();
}
return cls;
}
}
測(cè)試類自定義類加載器
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)換=來自于兩個(gè)不同的加載器
//Person p = (Person) o;//類型轉(zhuǎn)換錯(cuò)誤ClassCastException
//System.err.println(p);
}
}
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
解讀@NoArgsConstructor,@AllArgsConstructor,@RequiredArgsConstr
這篇文章主要介紹了解讀@NoArgsConstructor,@AllArgsConstructor,@RequiredArgsConstructor的區(qū)別及在springboot常用地方,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Java API方式調(diào)用Kafka各種協(xié)議的方法
本篇文章主要介紹了Java API方式調(diào)用Kafka各種協(xié)議的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
java數(shù)組實(shí)現(xiàn)隊(duì)列及環(huán)形隊(duì)列實(shí)現(xiàn)過程解析
這篇文章主要介紹了java數(shù)組實(shí)現(xiàn)隊(duì)列及環(huán)形隊(duì)列實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
Spring實(shí)戰(zhàn)之調(diào)用實(shí)例工廠方法創(chuàng)建Bean操作示例
這篇文章主要介紹了Spring實(shí)戰(zhàn)之調(diào)用實(shí)例工廠方法創(chuàng)建Bean操作,結(jié)合實(shí)例形式分析了實(shí)例工廠方法創(chuàng)建Bean相關(guān)配置、實(shí)現(xiàn)方法及操作注意事項(xiàng),需要的朋友可以參考下2019-11-11
JAVA基于Arrays.sort()實(shí)現(xiàn)數(shù)組升序和降序
這篇文章主要介紹了JAVA基于Arrays.sort()實(shí)現(xiàn)數(shù)組升序和降序,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
Springboot整合Mybatis傳值的常用方式總結(jié)
今天給大家?guī)淼氖顷P(guān)于Springboot的相關(guān)知識(shí),文章圍繞著Springboot整合Mybatis傳值的常用方式展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
java使用Socket實(shí)現(xiàn)SMTP協(xié)議發(fā)送郵件
這篇文章主要為大家詳細(xì)介紹了java使用Socket實(shí)現(xiàn)SMTP協(xié)議發(fā)送郵件的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-05-05
淺談在springboot中使用定時(shí)任務(wù)的方式
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識(shí),文章圍繞著在springboot中使用定時(shí)任務(wù)的方式展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06

