讀取Class文件

對于已經(jīng)出現(xiàn)在類路徑上的類,如果如需要動態(tài)裝載,可以使用classloader#loadClass或者Class#forname來實現(xiàn)。
那么對于不在類路徑的.class文件,需要裝載的時候就要用到URLClassLoader了。
I believe it's a ClassLoader you're after.

I suggest you start by looking at the example below which loads class files that are not on the class path.

// Create a File object on the root of the directory containing the class file
File file = new File("c:\\myclasses\\");

try {
    // Convert File to a URL
    URL url = file.toURL();          // file:/c:/myclasses/
    URL[] urls = new URL[]{url};

    // Create a new class loader with the directory
    ClassLoader cl = new URLClassLoader(urls);

    // Load in the class; MyClass.class should be located in
    // the directory file:/c:/myclasses/com/mycompany
    Class cls = cl.loadClass("com.mycompany.MyClass");
} catch (MalformedURLException e) {
} catch (ClassNotFoundException e) {
}

這里有兩個點需要注意

Package name is a part of full class name, not classpath item, so you need the following:

URL[] urls = {new URL("file:/F:/badge-dao/bin")}; 
...
selectedClass = classLoader.loadClass("com.badge.dao.impl.BadgeDaoImpl"); 
In your original code classloader can find a file named BadgeDaoImpl.class in file:/F:/badge-dao/bin/com/badge/dao/impl/, but its full class name (com.badge.dao.impl.BadgeDaoImpl) doesn't match the requested one (BadgeDaoImpl), therefore classloader throws a NoClassDefFoundError. Since you are catching only ClassNotFoundException, it looks like control silently passes to the finally block. When you change folder or class names so that .class file can't be found, ClassNotFoundException is thrown as expected.
  • URL:只能包含類路徑,不能包括包名,雖然包名也是以文件夾的形式呈現(xiàn),但包名是類名的一部分,所以類路徑與包名中的文件夾名要嚴格區(qū)分,類路徑就是類的根目錄,也就是包名的第一個部分所在的目錄
  • URL與jar : URL如果以'/'(windows'')結(jié)尾,那么這個URL代表了搜索類的目錄,反之代表了jar文件
From just glancing at the javadocs of [URLClassLoader](http://docs.oracle.com/javase/7/docs/api/java/net/URLClassLoader.html#URLClassLoader%28java.net.URL%5b%5d%29):
Any URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL is assumed to refer to a JAR file which will be downloaded and opened as needed.

The URL you're specifying ends with a slash, so the class loader expects to see .class
 files in that directory. Try specifying the full path to the JAR in the URL

裝載了類文件之后,這里有個坑。。

類中的各個字段

 // Caches for certain reflective results
    private static boolean useCaches = true;
    private volatile transient SoftReference<Field[]> declaredFields;
    private volatile transient SoftReference<Field[]> publicFields;
    private volatile transient SoftReference<Method[]> declaredMethods;
    private volatile transient SoftReference<Method[]> publicMethods;
    private volatile transient SoftReference<Constructor<T>[]> declaredConstructors;
    private volatile transient SoftReference<Constructor<T>[]> publicConstructors;
    // Intermediate results for getFields and getMethods
    private volatile transient SoftReference<Field[]> declaredPublicFields;
    private volatile transient SoftReference<Method[]> declaredPublicMethods;

可以看到都是軟引用,目的應(yīng)該是緩存
而在debug的時候,裝載了類文件,在沒有調(diào)用相關(guān)函數(shù)的時候,這些字段都顯示為null,調(diào)用了之后才會有對象,并不是讀到了空的類,這么設(shè)計的目的可能是為了方便JVM回收吧,以后再詳細看看。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,697評論 18 399
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,273評論 6 342
  • ClassLoader翻譯過來就是類加載器,普通的java開發(fā)者其實用到的不多,但對于某些框架開發(fā)者來說卻非常常見...
    時待吾閱讀 1,167評論 0 1
  • 很多時候,不想走了,因為累了; 很多時候,不想停留,因為想一直走; 很多時候,不想安于現(xiàn)狀,因為要改變; 很多時候...
    dreamer翟翟閱讀 376評論 0 2

友情鏈接更多精彩內(nèi)容