博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个例子深入理解ClassLoader
阅读量:6234 次
发布时间:2019-06-22

本文共 7925 字,大约阅读时间需要 26 分钟。

 

文件类加载器,该加载器重载了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.
(FileInputStream.java:146) at java.io.FileInputStream.
(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)

  

转载于:https://www.cnblogs.com/YDDMAX/p/5484131.html

你可能感兴趣的文章
Python2 JSON.load成Unicode的坑
查看>>
让Baidu和Google收录你的Hexo博客
查看>>
TypeScript 2019 路线图:更效率,更易用!
查看>>
【微信】第三方登录接口流程
查看>>
纯C实现的词法分析和lex实现的词法分析的对比
查看>>
喧喧发布 2.5.3 版本,主要提升系统稳定性,优化交互体验
查看>>
iOS应用显示一直安装,重启无效,也删除不了问题
查看>>
怎么把荣耀8x的手机备忘录导到电脑里?
查看>>
Elastic Search 新手入门笔记(一)
查看>>
把 Excel 透视表搬到 WEB 上
查看>>
Jenkins配合github实现前端项目自动化构建部署
查看>>
荐书:「时差党」——出国留学不是一件容易的事
查看>>
用户自定义结构数据与VARIANT转换
查看>>
java8-lambda
查看>>
Windows平台JxCore打包
查看>>
[译]ASP.NET Core依赖注入深入讨论
查看>>
设计模式(九)_代理模式
查看>>
02 回归算法 - 线性回归求解 θ(最大似然估计求解)
查看>>
【算法学习】算法的复杂度
查看>>
14、python常用模块
查看>>