對于已經(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回收吧,以后再詳細看看。