public void testLoaderDiffJar() throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
ClassA orgA = new ClassA();
orgA.print();
File classesDir = new File( "C:\\ClassA.jar ");
ClassLoader parentLoader = ClassA.class.getClassLoader();
URLClassLoader loader1 = new URLClassLoader(
new URL[] { classesDir.toURL() }, parentLoader);
Class cls1 = loader1.loadClass( "com.my.test.loader.ClassA ");
ClassA a = (ClassA) cls1.newInstance();
a.print();
}
----------------
问题:ClassLoader上来的类并没有替换原先的类。a.print();出来的信息还是旧的,请问这是为什么?
------解决方案--------------------
你没有明白 ClassLoader的 运行机制
ClassLoader在加载类的时候回首先把请求委托给它的父loader(也就是 你代码中的parentLoader ) 去加载
所以你的URLClassLoader在加载 ClassA的时候 会调用自己的父Loader 去加载
而这是 ClassA 已经被记载了,因为你前面的代码有ClassA 的操作
所以就出现了这种情况
要达到你的目的,要将 URLClassLoader 的机制改写一下 不让它委托加载
在defineClass(方法名我记不清出了)里面可以改写 你自己试试
不明白再交流
------解决方案--------------------
/*
JDK版本:jdk1.4.2与jdk1.6.0
目录文件位置:
F:\csdn\20070129\ClassA.class
F:\csdn\20070129\ClassA.java
F:\csdn\20070129\ClassA.jar
F:\csdn\20070129\my\ClassA.class
F:\csdn\20070129\my\ClassA.java
F:\csdn\20070129\ClassA.jar文件内容:
my\ClassA.class
my\ClassA.java
编译: F:\csdn\20070129> javac ClassA.java my\ClassA.java
打包: F:\csdn\20070129> jar -cvf ClassA.jar my
运行: F:\csdn\20070129> java ClassA
结果: 请猜一下????????能用双亲委派的原理分析出正确结果吗?????????
最后: 试试在getClassLoader()后加“.getParent()”看看结果如何?????????
试试在ClassA前加“my.”看看结果又是如何?????????
*/
//F:\csdn\20070129\my\ClassA.java源码
package my;
public class ClassA{
public void print() {
System.out.println( "my HACK ClassA ");
}
}
//F:\csdn\20070129\ClassA.java源码
import java.net.*;
import java.io.*;
public class ClassA extends ClassLoader {
public void print() {
System.out.println( "my ClassA ");
}
public static void main(String[] args) {
System.out.println( "第一种方式: ");
System.out.println( "----------------------------------- ");
ClassA orgA = new ClassA();
orgA.print();
System.out.println( "ClassLoader name: "+ClassA.class.getClassLoader());
File classesDir = new File( "ClassA.jar ");
try {
System.out.println( "\r\n第二种方式: ");
System.out.println( "----------------------------------- ");
ClassLoader parentLoader = ClassA.class.getClassLoader();
URLClassLoader loader = new URLClassLoader(
new URL[] { classesDir.toURL() }, parentLoader);
Class c = loader.loadClass( "my.ClassA ");
System.out.println( "ClassLoader name: "+c.getClassLoader());
ClassA a = (ClassA) c.newInstance();
a.print();
} catch (Throwable e) {
e.printStackTrace();
}
try {
System.out.println( "\r\n第三种方式: ");
System.out.println( "----------------------------------- ");