当前位置: 首页 > news >正文

Java classloader

文章目录

  • Classloader的继承性。
  • Classloader的隔离性。
  • 简单的plugin classloader
  • 自定义classloader

Classloader的继承性。

第一级叫做bootstrap classloader,加载JDK自带的类,也就是${JAVA_HOME}/lib下的类。
第二级叫做extern classloader,加载${JAVA_HOME}/lib/ext下的类。
第三级叫做system classloader,加载第三方的类,就是classpath里其他的类。
第四级及更高级叫做plugin classloader,是用户自己写的classloader或者new出来的URLClassLoader,加载classpath以外的类。在tomcat容器中,每个应用里的WEB-INF/lib和WEB-INF/classes就是通过tomcat自定义的classloader去加载的。

Classloader的隔离性。

  1. 父级不能调用子级的类。
    比如extern classloader里加载的class不能调用system classloader加载的类,会抛class not found异常.
  2. 同一级不同classloader加载的类不能互相调用。
    比如有两个plugin classloader, loader A 与loader B。loader A加载的类class A不能调用loader B加载的类 class B.
  3. 无法获取bootstrap Classloader的实例。
    System.out.println(String.class.getClassLoader());
    这个输出结果是null
    总而言之,只能child加载的类调用parent加载的类。兄弟及各种远房亲戚不能互相调用。

简单的plugin classloader

直接使用jdk自带的url classloader就可以加载任意jar包里的类了。
比如以下代码

finalURLurl=newURL("file:///C:/Users/Ryan/IdeaProjects/learn/classloader/heap-1.0.jar");finalURLClassLoaderclassLoader=newURLClassLoader(newURL[]{url});finalClass<?>heapClass=classLoader.loadClass("net.cloudsun.head.SmallHeap");finalConstructor<?>constructor=heapClass.getConstructor();finalObjecto=constructor.newInstance();finalMethodadd=heapClass.getMethod("add",java.lang.Comparable.class);for(inti=0;i<10;i++){add.invoke(o,-i);}System.out.println(o);

自定义classloader

当不能提供url时,比如jar包不在磁盘里,也不在http服务器上,或者jar包是加密的。只能自己写classloader进行类的加载。
自己写classloader最终必须继承Classloader类。因为这个类有个保护型且final的defineClass方法,传入类的字节码,也就是byte[],就可以加载一个类。也就是说class的来源是byte[]。
比如

publicclassJarClassLoaderextendsClassLoader{@OverridepublicClass<?>loadClass(Stringname)throwsClassNotFoundException{// 从jar包里取byte数组try{JarFilejarFile=newJarFile("heap-1.0.jar");finalbyte[]bytes=JarUtils.getByte(jarFile,name);if(bytes==null){returnsuper.loadClass(name);}returnsuper.defineClass(name,bytes,0,bytes.length);}catch(IOExceptione){e.printStackTrace();returnnull;}}}

上述代码的JarUtils是一个自己写的工具类。

publicstaticbyte[]getByte(JarFilejarFile,StringclassName){finalStringentry=className.replace('.','/')+".class";finalJarEntryjarEntry=jarFile.getJarEntry(entry);if(jarEntry==null){returnnull;}try(finalInputStreaminputStream=jarFile.getInputStream(jarEntry)){returnIOUtils.toByteArray(inputStream);}catch(IOExceptione){e.printStackTrace();returnnull;}}

当然这个classloader写得并不规范。因为规范的classloader首先要调用parent classloader去加载类,如果parent加载失败,再自己加载,而且加载的class必须缓存起来。因为从字节码加载class的开销是非常巨大的。当然前三级JDK自带的的classloader都会在loadClass方法里去检查class是否已经加载。所以只要每级class loader优先调用parent classloader,就可以自动实现class的缓存。

http://www.cnnetsun.cn/news/193378.html

相关文章:

  • Keil5MDK安装及界面介绍:通俗解释版
  • 终极指南:5分钟让Windows完美显示iPhone HEIC照片缩略图
  • Cimoc:Android平台终极漫画阅读解决方案
  • TrollInstallerX下载被拦截?这些方法让你顺利安装
  • Draw.io Mermaid插件终极指南:从代码到图表的智能革命
  • 如何快速掌握HSTracker:macOS炉石传说智能助手的完整指南
  • VDA5050协议终极指南:AGV通信标准的完整解析与实战应用
  • 终极方案:5分钟快速修复Path of Exile GGPK文件解析难题
  • 终极文件下载神器:Nugget让你的下载效率翻倍
  • 三步搞定:OpenWrt路由器音乐解锁完整指南
  • DeepL翻译插件:一键解决网页阅读语言障碍的智能神器
  • zhihu-api知乎非官方API完全攻略:从零开始掌握知乎数据获取
  • GeoJSON在线编辑器完全指南:从零开始掌握地理数据处理
  • 3、Windows 8应用开发与C++11新特性解析
  • 京东抢购助手:5个实用技巧让你告别手慢无的烦恼
  • LangFlow中的用量预警系统:提前通知接近限额
  • 开源视觉AI的翘楚,揭秘Qwen-VL,,“看、懂、想”三位一体的内核
  • 5步快速上手ColabFold:AI蛋白质结构预测的完整指南
  • 抖音无水印视频下载工具完全使用教程:从入门到精通
  • DeepL翻译插件:打破语言障碍的浏览器智能助手
  • PatreonDownloader终极指南:5步轻松备份创作者独家内容
  • LangFlow与舆情监控结合:品牌声誉实时跟踪
  • WeChatExtension-ForMac:让你的Mac微信效率提升300%的终极方案
  • SGLang学习笔记
  • ZLUDA实战攻略:在AMD显卡上高效运行CUDA应用的完整方案
  • ImageGlass图片查看器:让Windows看图体验焕然一新的轻量级神器
  • 抖音无水印视频下载器:3分钟掌握永久保存高清视频技巧
  • 新手必看:RPG Maker MV资源提取工具完全操作手册
  • 前后端分离七彩云南文化旅游网站系统|SpringBoot+Vue+MyBatis+MySQL完整源码+部署教程
  • 深入浅出讲解Proteus在现代Windows系统的安装逻辑