Java ClassLoad作用只是把Java class文件加载到内存中。需要你自己去把内存中的字节码去初始化你为你的对象。
这里有个blog :http://my.oschina.net/u/1412027/blog/186920 Class.forName和ClassLoader.loadClass区别 讲的非常清楚。
引用“ forName("")得到的class是已经初始化完成的
loadClass("")得到的class是还没有连接的”
还有数据库的驱动加载的玩法,很有意思。
这个Blog http://www.blogjava.net/vincent/archive/2008/08/30/225804.html “通过ClassLoader说明容器热部署实现机制” 讲到了 classloader的双亲委派机制,以及判断一个类是否是重复加载需要判断,是否是同一段字节码和同一个类加载器。等特性 很不错。
我在制作networkClassLoader的测试环境时,Eclipse可以导出的jar需要解压,然后放到如apache的htdocs下面去,可以理解为是拼URL地址来找到单个文件的。第一次玩这个需要注意下。
如果要定义ClassLoader字需要是实现findclass函数即可。
参考:http://blog.csdn.net/xyang81/article/details/7292380
向以上blog的作者道一声谢谢。
来段测试代码:
public static void main(String args[]) throws ClassNotFoundException,
InstantiationException, IllegalAccessException,
MalformedURLException {
String rootUrl = "http://127.0.0.1/classes/";
String className = "com.jcloud.test.classload.NetClassLoaderSimple";
URL[] urlarr = new URL[1];
urlarr[0] = new URL(rootUrl);
NetClassLoaderMain NetClassLoaderMain1 = new NetClassLoaderMain(urlarr);
NetClassLoaderMain NetClassLoaderMain2 = new NetClassLoaderMain(urlarr);
//只是字节码
Class<?> clazz1 = NetClassLoaderMain1.loadClass(className);
Class<?> clazz2 = NetClassLoaderMain2.loadClass(className);
//需要自己实例化
Object obj1 = clazz1.newInstance();
Object obj2 = clazz2.newInstance();
System.out.println(obj1);
System.out.println(obj2);
// ((com.jcloud.test.NetClassLoaderSimple)obj1).setNetClassLoaderSimple(obj2);
try {
clazz1.getMethod("setNetClassLoaderSimple", Object.class).invoke(obj1,
obj2);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
-------------这段代码测试不解压jar包---
做法是:
1、把URLClassLoader中的addURL方法设置为可访问。
2、调用addURL把jar包放到Classloader加载列表中。
3、加载对应的class。
package com.jcloud.test.classload.jar;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoaderJarTest {
public static Method initAddMethod() {
try {
Method add = URLClassLoader.class.getDeclaredMethod("addURL",
new Class[] { URL.class });
//原来的addURL方法为protected
add.setAccessible(true);
return add;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Method addURL = null;
public static URLClassLoader classloader = null;
public static void main(String[] args) {
/*
* 系统加载jar
*/
try {
// 系统ClassLoader只能加载.jar
// 动态加载jar
addURL = initAddMethod();
classloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
System.out.println(classloader);
File jarFile = new File("C:\\xampp\\htdocs\\classes\\test.jar");
URL classUrl = jarFile.toURI().toURL();
System.out.println(classUrl);
addURL.invoke(classloader, new Object[] { classUrl });
String className = "com.jcloud.test.classload.NetClassLoaderSimple";
Class<?> c = classloader.loadClass(className);
// Class<?> c = Class.forName(className);
Object obj = c.newInstance();
Object obj2 = c.newInstance();
// 被调用函数的参数
System.out.println("obj=" +obj);
System.out.println("obj2=" + obj2);
// 之定义的方法setNetClassLoaderSimple
Method method2 = c.getDeclaredMethod("setNetClassLoaderSimple",
Object.class);
method2.invoke(obj, obj2);
} catch (Exception exp) {
exp.printStackTrace();
}
}
}