loadClass(String name);根据cn.com.akl.DemoController查找并加载类。先在parent或bootstrap中查找,有则给jvm加载。没有则按照findClass方法查找。
findClass();默认抛出一个ClassNotFoundException,如果需要自己重新覆盖实现。
defineClass();是将你定义的字节码文件经过字节数组流解密之后,将该字节流数组生成字节码文件,也就是该类的文件的类名.class。通常用在重写findClass中,返回一个Class。如果不想要把class加载到jvm中,也可以单独使用getConstructor和newInstance来实例化一个对象。
defineClass( byte[] b ,0, b.length) ,这样生成的字节码就是默认的字节码文件。
defineClass(String name , byte[] b , 0, b.length ),声明时,name 是指定该类名,这里的类名是指包含它所属的包名+类名
例:从网络加载class
public class ClassLoaderTest {
public static void main(String[] args) {
try {
/*ClassLoader loader = ClassLoaderTest.class.getClassLoader(); //获得ClassLoaderTest这个类的类加载器
while(loader != null) {
System.out.println(loader);
loader = loader.getParent(); //获得父加载器的引用
}
System.out.println(loader);*/
String rootUrl = "http://localhost:8080/akl_freemaker/classResource";
NetworkClassLoader networkClassLoader = new NetworkClassLoader(rootUrl);
String classname = "cn.com.akl.DemoController";
Class clazz = networkClassLoader.loadClass(classname);
System.out.println(clazz.getClassLoader());
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class NetworkClassLoader extends ClassLoader {
private String rootUrl;
public NetworkClassLoader(String rootUrl) {
this.rootUrl = rootUrl;
}
@Override
protected Class> findClass(String name) throws ClassNotFoundException {
Class clazz = null;//this.findLoadedClass(name); // 父类已加载
//if (clazz == null) { //检查该类是否已被加载过
byte[] classData = getClassData(name); //根据类的二进制名称,获得该class文件的字节码数组
if (classData == null) {
throw new ClassNotFoundException();
}
clazz = defineClass(name, classData, 0, classData.length); //将class的字节码数组转换成Class类的实例
//}
return clazz;
}
private byte[] getClassData(String name) {
InputStream is = null;
try {
String path = classNameToPath(name);
URL url = new URL(path);
byte[] buff = new byte[1024*4];
int len = -1;
is = url.openStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((len = is.read(buff)) != -1) {
baos.write(buff,0,len);
}
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
return null;
}
private String classNameToPath(String name) {
return rootUrl + "/" + name.replace(".", "/") + ".class";
}
}