关于类加载器的讨论,详细可参考http://www.ibm.com/developerworks/cn/java/j-lo-classloader/
这里只展示我参考《深入理解JAVA虚拟机》上的一个例子。
第一个类:MyOwnLoader
package classLoader;
import java.io.IOException;
import java.io.InputStream;
public class MyOwnLoader {
public static void main(String[] args) {
ClassLoader loader = new ClassLoader() {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
String className = name.substring(name.lastIndexOf(".") + 1) + ".class";
try {
InputStream is = getClass().getResourceAsStream(className);
if (is == null) {
return super.loadClass(name);
}
int length = is.available();
byte[] bytes = new byte[length];
is.read(bytes);
return defineClass(name, bytes, 0, bytes.length);
} catch (IOException e) {
throw new ClassNotFoundException("can't load class:" + className, e);
}
};
};
try {
Object object = loader.loadClass("classLoader.ClassLoaderTest").newInstance();
System.out.println(object.getClass());
System.out.println(object instanceof classLoader.ClassLoaderTest);
} catch (Exception e) {
e.printStackTrace();
}
}
}
第二个类:
package classLoader;
public class ClassLoaderTest {
public ClassLoaderTest() {
System.out.println("ClassLoaderTest init");
}
public static void main(String... strings) {
System.out.println("ClassLoaderTest main begin");
}
}
这里需要注意的是由于我们使用了自定义的类加载器来加载类,当我们无法加载有些类的时候,例如java.lang.Object的时候,应该调用父类加载器来加载,最终会调用SUN公司提供的启动类加载器。
关于defineClass()的方法可参考:
protected final Class<?> defineClass(String name,
byte[] b,
int off,
int len,
ProtectionDomain protectionDomain)
throws ClassFormatError
每个参数的含义是:
参数:
name
- 所需类的
二进制名称,如果不知道此名称,则该参数为
null
b
- 组成类数据的字节。从
off 到
off+len-1 的字节应该具有由《
Java Virtual Machine Specification》定义的有效类文件的格式。
off
- 类数据的
b 中的起始偏移量
len
- 类数据的长度
protectionDomain
- 类的 ProtectionDomain
返回: 从数据中创建的
Class 对象和可选的
ProtectionDomain。