JAVA自定义类加载器入门
关于类加载器的讨论,详细可参考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