标签:
文件类加载器,该加载器重载了loadClass方法,逻辑是只读取文件来加载类,不委托给父类加载器进行加载
package com.ydd.study.hello.classloader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class FileSystemClassLoader extends ClassLoader { private String rootDir; public FileSystemClassLoader(String rootDir) { this.rootDir = rootDir; } protected Class<?> findClass(String name) throws ClassNotFoundException { byte[] classData = getClassData(name); if (classData == null) { throw new ClassNotFoundException(); } else { return defineClass(name, classData, 0, classData.length); } } @Override public Class<?> loadClass(String name) { try { return findClass(name); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } private byte[] getClassData(String className) { String path = classNameToPath(className); try { InputStream ins = new FileInputStream(path); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int bufferSize = 4096; byte[] buffer = new byte[bufferSize]; int bytesNumRead = 0; while ((bytesNumRead = ins.read(buffer)) != -1) { baos.write(buffer, 0, bytesNumRead); } return baos.toByteArray(); } catch (IOException e) { e.printStackTrace(); } return null; } private String classNameToPath(String className) { return rootDir + File.separatorChar + className.replace(‘.‘, File.separatorChar) + ".class"; } }
测试代码
package com.ydd.study.hello.classloader; import org.junit.Test; public class FileSystemClassLoaderTest { @Test public void test() { FileSystemClassLoader fileSystemClassLoader=new FileSystemClassLoader("D:\\"); try { Class<?>c=fileSystemClassLoader.loadClass("TestClass"); System.out.println(c); Object testClass=(c.newInstance()); System.out.println(c+"|"+testClass); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
从下面的输出,可以看出:
1、在加载TestClass类时就已经引起其他类的加载了。
2、不要轻易重载loadClass(),双亲制很重要,否则会引起一个类存在多个Class对象。
3、类A依赖的其他类的加载,全部都是由类A的ClassLoader进行初始发起加载
java.io.FileNotFoundException: D:\java\lang\Object.class (系统找不到指定的路径。) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.<init>(FileInputStream.java:146) at java.io.FileInputStream.<init>(FileInputStream.java:101) at com.ydd.study.hello.classloader.FileSystemClassLoader.getClassData(FileSystemClassLoader.java:42) at com.ydd.study.hello.classloader.FileSystemClassLoader.findClass(FileSystemClassLoader.java:17) at com.ydd.study.hello.classloader.FileSystemClassLoader.loadClass(FileSystemClassLoader.java:29) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) at java.lang.ClassLoader.defineClass(ClassLoader.java:643) at com.ydd.study.hello.classloader.FileSystemClassLoader.findClass(FileSystemClassLoader.java:22) at com.ydd.study.hello.classloader.FileSystemClassLoader.loadClass(FileSystemClassLoader.java:29) at com.ydd.study.hello.classloader.FileSystemClassLoaderTest.test(FileSystemClassLoaderTest.java:12) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) java.lang.ClassNotFoundException at com.ydd.study.hello.classloader.FileSystemClassLoader.findClass(FileSystemClassLoader.java:19) at com.ydd.study.hello.classloader.FileSystemClassLoader.loadClass(FileSystemClassLoader.java:29) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) at java.lang.ClassLoader.defineClass(ClassLoader.java:643) at com.ydd.study.hello.classloader.FileSystemClassLoader.findClass(FileSystemClassLoader.java:22) at com.ydd.study.hello.classloader.FileSystemClassLoader.loadClass(FileSystemClassLoader.java:29) at com.ydd.study.hello.classloader.FileSystemClassLoaderTest.test(FileSystemClassLoaderTest.java:12) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
标签:
原文地址:http://www.cnblogs.com/YDDMAX/p/5484131.html