最近作了一个根据同一模块的不一样jar版本作同时测试的工具,感受挺有意思,特此记录。html
把类加载阶段中的“经过一个类的全限定名(博主注:绝对路径)来获取描述此类的二进制字节流”这个动做放在Java虚拟机外部去实现,以便让应用程序本身决定如何去获取所须要的类。实现这个动做的代码模块成为”类加载器“。摘自周志明的《深刻理解Java虚拟机》java
总之,ClassLoader很重要,Java世界须要它。eclipse
本人在本地生成了test1.jar和test2.jar两个jar包。这两个jar都有类com.array7.jvm.classloader.Target
,此Demo要实现的是同时将这两个jar包的同名类加载到JVM而且各自执行。
** test1.jar Target.java **jvm
package com.array7.jvm.classloader; public class Target { public static void main(String[] args) { System.out.print("test1"); } }
** test2.jar Target.java **工具
package com.array7.jvm.classloader; public class Target { public static void main(String[] args) { System.out.print("test2"); } }
** TestDriver**测试
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { ClassLoader loader1 = new URLClassLoader(new URL[]{new URL("file:/home/liushijie/workspace/test/out/artifacts/test1/test1.jar")}, TestDriver.class.getClassLoader()); ClassLoader loader2 = new URLClassLoader(new URL[]{new URL("file:/home/liushijie/workspace/test/out/artifacts/test2/test2.jar")}, TestDriver.class.getClassLoader()); String className = "com.array7.jvm.classloader.Target"; // loader1 System.out.print("test1.jar \t"); Class clazz1 = Class.forName(className, true, loader1); clazz1.getMethod("main", String[].class).invoke(null, (Object) null); System.out.println(); // loader2 System.out.print("test2.jar \t"); Class clazz2 = Class.forName(className, true, loader2); clazz2.getMethod("main", String[].class).invoke(null, (Object) null); System.out.println(); System.out.println("实例化后是否相等:" + clazz1.equals(clazz2)); }
test1.jar test1 test2.jar test2 实例化后是否相等:false