類加載
所有類加載器,都是ClassLoader的子類。
類加載器永遠(yuǎn)以.class運(yùn)行的目錄為準(zhǔn)。
讀取classpath根目錄下的文件有以下幾種方式:
1 在java項目中可以通過以下方式獲取classspath下的文件:
public void abc(){ //每一種讀取方法,使用某個類獲取Appclassloader ClassLoader cl = ReadFile.class.getClassLoader(); URL url = cl.getResource("a.txt"); System.err.在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();//獲取父類加載器 } }}運(yùn)行的結(jié)果:
1類加載器是:class org.apache.catalina.loader.WebappClassLoader2類加載器是:class org.apache.catalina.loader.StandardClassLoader3類加載器是:class sun.misc.Launcher$AppClassLoader4類加載器是: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); }}
新聞熱點(diǎn)
疑難解答