下图来自:http://blog.csdn.net/jiangwei0910410003/article/details/17733153
package com.test.jvm.common; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; /** * 自定义的类加载器 */ public class MyClassLoader extends ClassLoader { private String name; //加载器的名字 // private String className; //被加载类的全名 private String path = "D:/workspace/eclipse-workspace64bit17-forPersonalProject/openbank-parent/openbank-test/src/test/java/"; //加载类的路径 private final String fileType = ".class"; //class文件的扩展名 public MyClassLoader(String name) { super(); //让系统类加载器成为该类加载器的父类 this.name = name; } public MyClassLoader(ClassLoader parent,String name) { super(parent); //显示指定该类加载器的的父加载器 this.name = name; } @Override public String toString() { // TODO Auto-generated method stub return this.name; } // TODO Auto-generated method stub private byte[] loadClassData(String className) { InputStream inputStream = null; byte[] data = null; ByteArrayOutputStream byteArrayOutputStream = null; try { className = className.replace('.', '/'); inputStream = new FileInputStream(new File(path+className+fileType)); byteArrayOutputStream = new ByteArrayOutputStream(); int ch = 0; while(-1 != (ch = inputStream.read())) { byteArrayOutputStream.write(ch); } data = byteArrayOutputStream.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { try { inputStream.close(); byteArrayOutputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return data; } @Override protected Class<?> findClass(String className) throws ClassNotFoundException { byte[] data =this.loadClassData(className); //将字节数组转换成Class对象 return this.defineClass(className, data, 0, data.length); } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { System.out.println(System.getProperty("java.class.path")); System.out.println("------------------"); MyClassLoader loader1 = new MyClassLoader("loader1"); // loader1.setPath("D:/temp/serverlib"); MyClassLoader loader2 = new MyClassLoader(loader1,"loader2"); //将loader1作为loader2的父加载器 // loader2.setPath("D:/temp/clientlib"); MyClassLoader loader3 = new MyClassLoader(null,"loader3"); //将第一个参数设为空表示父加载器为根加载器 // loader3.setPath("d:/temp/systemlib"); test(loader2); System.out.println("-----------------"); test(loader3); } public static void test(ClassLoader loader) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class clazz = loader.loadClass("com.test.jvm.common.Sample"); Object object = clazz.newInstance(); } }
public class Sample { public int v1 = 1; public Sample() { System.out.println("Sample is loaded by: "+this.getClass().getClassLoader()); new Dog(); } }
public class Dog { public Dog() { System.out.println("Dog is loaded by: "+this.getClass().getClassLoader()); } }
我将编译后的Sample.class和Dog.class放在他们源代码所在的包里
运行结果:
D:\workspace\eclipse-workspace64bit17-forPersonalProject\openbank-parent\openbank-test\target\test-classes;D:\workspace\eclipse-workspace64bit17-forPersonalProject\openbank-parent\openbank-test\target\classes;D:\IDE\eclipse\plugins\org.testng.eclipse_6.9.13.201609291640\lib\testng.jar;D:\IDE\eclipse\plugins\org.testng.eclipse_6.9.13.201609291640\lib\jcommander.jar;D:\IDE\eclipse\plugins\org.testng.eclipse_6.9.13.201609291640\lib\bsh-2.0b4.jar;D:\IDE\eclipse\plugins\org.testng.eclipse_6.9.13.201609291640\lib\snakeyaml.jar;D:\workspace\eclipse-workspace64bit17-forPersonalProject\openbank-parent\openbank-batch\target\classes;C:\Users\Ash\.m2\repository\org\springframework\batch\spring-batch-core\3.0.6.RELEASE\spring-batch-core-3.0.6.RELEASE.jar;C:\Users\Ash\.m2\repository\com\ibm\jbatch\com.ibm.jbatch-tck-spi\1.0\com.ibm.jbatch-tck-spi-1.0.jar;C:\Users\Ash\.m2\repository\javax\batch\javax.batch-api\1.0\javax.batch-api-1.0.jar;C:\Users\Ash\.m2\repository\com\thoughtworks\xstream\xstream\1.4.7\xstream-1.4.7.jar;C:\Users\Ash\.m2\repository\xmlpull\xmlpull\1.1.3.1\xmlpull-1.1.3.1.jar;C:\Users\Ash\.m2\repository\xpp3\xpp3_min\1.1.4c\xpp3_min-1.1.4c.jar;C:\Users\Ash\.m2\repository\org\codehaus\jettison\jettison\1.2\jettison-1.2.jar;C:\Users\Ash\.m2\repository\org\springframework\batch\spring-batch-infrastructure\3.0.6.RELEASE\spring-batch-infrastructure-3.0.6.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\retry\spring-retry\1.1.0.RELEASE\spring-retry-1.1.0.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-beans\4.1.9.RELEASE\spring-beans-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-context\4.1.9.RELEASE\spring-context-4.1.9.RELEASE.jar;D:\workspace\eclipse-workspace64bit17-forPersonalProject\openbank-parent\openbank-base\target\classes;C:\Users\Ash\.m2\repository\commons-dbcp\commons-dbcp\1.4\commons-dbcp-1.4.jar;C:\Users\Ash\.m2\repository\commons-pool\commons-pool\1.6\commons-pool-1.6.jar;C:\Users\Ash\.m2\repository\com\oracle\ojdbc6\11.2.0.4\ojdbc6-11.2.0.4.jar;C:\Users\Ash\.m2\repository\junit\junit\3.8.1\junit-3.8.1.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter-web\1.2.8.RELEASE\spring-boot-starter-web-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter\1.2.8.RELEASE\spring-boot-starter-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot\1.2.8.RELEASE\spring-boot-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\1.2.8.RELEASE\spring-boot-autoconfigure-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter-logging\1.2.8.RELEASE\spring-boot-starter-logging-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\slf4j\jul-to-slf4j\1.7.13\jul-to-slf4j-1.7.13.jar;C:\Users\Ash\.m2\repository\org\slf4j\log4j-over-slf4j\1.7.13\log4j-over-slf4j-1.7.13.jar;C:\Users\Ash\.m2\repository\ch\qos\logback\logback-classic\1.1.3\logback-classic-1.1.3.jar;C:\Users\Ash\.m2\repository\ch\qos\logback\logback-core\1.1.3\logback-core-1.1.3.jar;C:\Users\Ash\.m2\repository\org\yaml\snakeyaml\1.14\snakeyaml-1.14.jar;C:\Users\Ash\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.4.6\jackson-databind-2.4.6.jar;C:\Users\Ash\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.4.6\jackson-annotations-2.4.6.jar;C:\Users\Ash\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.4.6\jackson-core-2.4.6.jar;C:\Users\Ash\.m2\repository\org\hibernate\hibernate-validator\5.1.3.Final\hibernate-validator-5.1.3.Final.jar;C:\Users\Ash\.m2\repository\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;C:\Users\Ash\.m2\repository\org\jboss\logging\jboss-logging\3.1.3.GA\jboss-logging-3.1.3.GA.jar;C:\Users\Ash\.m2\repository\com\fasterxml\classmate\1.0.0\classmate-1.0.0.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-core\4.1.9.RELEASE\spring-core-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-web\4.1.9.RELEASE\spring-web-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-webmvc\4.1.9.RELEASE\spring-webmvc-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-expression\4.1.9.RELEASE\spring-expression-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter-batch\1.2.8.RELEASE\spring-boot-starter-batch-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\hsqldb\hsqldb\2.3.3\hsqldb-2.3.3.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-jdbc\4.1.9.RELEASE\spring-jdbc-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter-jetty\1.2.8.RELEASE\spring-boot-starter-jetty-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-jsp\9.2.14.v20151106\jetty-jsp-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\toolchain\jetty-schemas\3.1.M0\jetty-schemas-3.1.M0.jar;C:\Users\Ash\.m2\repository\javax\servlet\javax.servlet-api\3.1.0\javax.servlet-api-3.1.0.jar;C:\Users\Ash\.m2\repository\javax\servlet\jsp\javax.servlet.jsp-api\2.3.1\javax.servlet.jsp-api-2.3.1.jar;C:\Users\Ash\.m2\repository\org\glassfish\web\javax.servlet.jsp\2.3.2\javax.servlet.jsp-2.3.2.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\orbit\javax.servlet.jsp.jstl\1.2.0.v201105211821\javax.servlet.jsp.jstl-1.2.0.v201105211821.jar;C:\Users\Ash\.m2\repository\org\glassfish\web\javax.servlet.jsp.jstl\1.2.2\javax.servlet.jsp.jstl-1.2.2.jar;C:\Users\Ash\.m2\repository\org\glassfish\javax.el\3.0.0\javax.el-3.0.0.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\orbit\org.eclipse.jdt.core\3.8.2.v20130121\org.eclipse.jdt.core-3.8.2.v20130121.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-webapp\9.2.14.v20151106\jetty-webapp-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-xml\9.2.14.v20151106\jetty-xml-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-util\9.2.14.v20151106\jetty-util-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-servlet\9.2.14.v20151106\jetty-servlet-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-security\9.2.14.v20151106\jetty-security-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-server\9.2.14.v20151106\jetty-server-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\websocket-server\9.2.14.v20151106\websocket-server-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\websocket-common\9.2.14.v20151106\websocket-common-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\websocket-api\9.2.14.v20151106\websocket-api-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-io\9.2.14.v20151106\jetty-io-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\websocket-client\9.2.14.v20151106\websocket-client-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\websocket-servlet\9.2.14.v20151106\websocket-servlet-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-http\9.2.14.v20151106\jetty-http-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\javax-websocket-server-impl\9.2.14.v20151106\javax-websocket-server-impl-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-annotations\9.2.14.v20151106\jetty-annotations-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-plus\9.2.14.v20151106\jetty-plus-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\jetty-jndi\9.2.14.v20151106\jetty-jndi-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\javax\annotation\javax.annotation-api\1.2\javax.annotation-api-1.2.jar;C:\Users\Ash\.m2\repository\org\ow2\asm\asm\5.0.1\asm-5.0.1.jar;C:\Users\Ash\.m2\repository\org\ow2\asm\asm-commons\5.0.1\asm-commons-5.0.1.jar;C:\Users\Ash\.m2\repository\org\ow2\asm\asm-tree\5.0.1\asm-tree-5.0.1.jar;C:\Users\Ash\.m2\repository\org\eclipse\jetty\websocket\javax-websocket-client-impl\9.2.14.v20151106\javax-websocket-client-impl-9.2.14.v20151106.jar;C:\Users\Ash\.m2\repository\javax\websocket\javax.websocket-api\1.0\javax.websocket-api-1.0.jar;C:\Users\Ash\.m2\repository\org\springframework\data\spring-data-redis\1.7.0.RELEASE\spring-data-redis-1.7.0.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\data\spring-data-keyvalue\1.1.0.RELEASE\spring-data-keyvalue-1.1.0.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\data\spring-data-commons\1.9.4.RELEASE\spring-data-commons-1.9.4.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-tx\4.1.9.RELEASE\spring-tx-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-oxm\4.1.9.RELEASE\spring-oxm-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-aop\4.1.9.RELEASE\spring-aop-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-context-support\4.1.9.RELEASE\spring-context-support-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\slf4j\slf4j-api\1.7.19\slf4j-api-1.7.19.jar;C:\Users\Ash\.m2\repository\org\slf4j\jcl-over-slf4j\1.7.13\jcl-over-slf4j-1.7.13.jar;C:\Users\Ash\.m2\repository\redis\clients\jedis\2.8.0\jedis-2.8.0.jar;C:\Users\Ash\.m2\repository\org\apache\commons\commons-pool2\2.2\commons-pool2-2.2.jar;C:\Users\Ash\.m2\repository\org\springframework\boot\spring-boot-starter-test\1.2.8.RELEASE\spring-boot-starter-test-1.2.8.RELEASE.jar;C:\Users\Ash\.m2\repository\org\mockito\mockito-core\1.10.19\mockito-core-1.10.19.jar;C:\Users\Ash\.m2\repository\org\objenesis\objenesis\2.1\objenesis-2.1.jar;C:\Users\Ash\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\Ash\.m2\repository\org\hamcrest\hamcrest-library\1.3\hamcrest-library-1.3.jar;C:\Users\Ash\.m2\repository\org\springframework\spring-test\4.1.9.RELEASE\spring-test-4.1.9.RELEASE.jar;C:\Users\Ash\.m2\repository\org\testng\testng\6.9.10\testng-6.9.10.jar;C:\Users\Ash\.m2\repository\com\beust\jcommander\1.48\jcommander-1.48.jar;C:\Users\Ash\.m2\repository\org\beanshell\bsh\2.0b4\bsh-2.0b4.jar ------------------ Sample is loaded by: sun.misc.Launcher$AppClassLoader@2d8eef25 Dog is loaded by: sun.misc.Launcher$AppClassLoader@2d8eef25 ----------------- Sample is loaded by: loader3 Dog is loaded by: loader3
如果我将Sample.class和Dog.class放在非System.getProperty("java.class.path")路径下,则AppClassLoader将无法找到这个类,则加载这个类的任务将落在自定义类加载器身上,那么上面的输出结果将会不同