当前位置: 首页 > 科技观察

JDK君最近有点烦

时间:2023-03-11 23:39:25 科技观察

1JDK君有点烦骄傲的基础设施。回想java刚诞生的时候,package帮助程序员更好的组织java类,jar文件把class文件打包成压缩包,classpath这么多年一直在苦苦寻找class文件,没有出错。你为什么抱怨他们?前天用户系统跑过来,说他有两个包,com.foo.db.api。一些看不懂的程序员还是直接使用impl包,屡禁不止。用户系统愤愤不平的问道:你就没有办法让impl包对外私有吗?如果你不支持,我们就全部转给OGSi,你后悔都来不及!还有,昨天订票系统说他有两个模块,模块A依赖json_1.1.jar,模块B依赖json_2.0.jar,但是这两个jar不兼容,怎么放在类路径上?JDK觉得票务系统很变态,怎么会出现这样的代码,这不是在折磨自己吗?但是转念一想,主要问题还是自己的classpath。这个所谓的classpath是一个扁平的线性结构,jar之间的依赖关系应该是一个有向图!今天有个小伙说要开发物联网应用,内存有限。他发现JDK和JRE太大了,动辄上百兆。更要命的是,里面有很多东西是他们用不到的,比如接口相关的jar,但是不能从JDK中移除。能否根据自己的需要裁剪JDK?如果前两个要求合理的话,这位兄弟的要求简直就是一场革命,JDK会自己作死。2模块化虽然JDK已经很成熟了,但是用户的需求也不容忽视。经过半个月的闭关思考JDK,终于想出了一个大招:做粗粒度模块化!他邀请大家一起讨论。“模块化?粗粒度?” 一听到这个消息, 的订单系统就跳起来了,生怕自己搞砸了。“是啊,模块一般指的是一个独立的单元,精确地声明了对外的接口和依赖关系。想一想,人类在开发中基本上都是把jar文件当作“模块”,每个jar文件都包含一些包,但jar文件本质上是一堆压缩的.class文件。》《那怎么办?》 用户系统的好奇心被激发了,特别想控制包的权限。这个文件定义了模块的名称,它对外提供的接口,以及依赖,就像这样:“用户系统很兴奋,这简直就是为他量身定做:”嗯,这个很容易理解,模块名的这个jar叫com.foo.db,依赖另一个模块java.sql,这个export意味着别人只能访问com.foo.db.api包下的类,com.foo.db.impl不能访问,正确的?"com.foo.db.jar文件内容如下:module-def.xmlcom.foo.db.api.XXXX.classcom.foo.db.api.XXXX.class......com.foo.db.impl.XXXX.classcom.foo.db.impl.XXXX.class……JDK赞许地说:“不错,这就是所谓的粗粒度模块。原来的java类也可以称为模块,但是粒度太细了。现在我们把一组类封装成一个jar文件,加上一个声明文件,就成了一个粗粒度的模块。当然,你完全可以认为我必须自己做增强。我必须能够识别模块定义并正确设置访问权限。”用户系统说:“唉,其实我最讨厌又臭又长的xml了。能不能用java来描述一下,就叫module-info.java吧。”JDK笑道:“看来你想的很深啊。我也喜欢这样清爽的表达方式,但是java语法也要加强。添加关键字,如module、requries、exports。“现在:com.foo.db.jar文件包含以下内容:module-info.classcom.foo.db.api.XXXXcom.foo.db.api.XXXX...com.foo.db.impl.XXXXcom.foo.db.impl.XXXX......3JDK自己的革命开发物联网的家伙问:“先生。JDK,你要不要把它模块化,这样我就可以切掉我也用模块了。”“是的,如果你的上层是模块化的,我也必须这样做,我必须先做出来,这样你就可以方便地使用它。这对我来说是一场巨大的革命。我必须整理我的数千个类,以形成一个定义明确且隔离良好的模块。我现在才总结了一部分:java.desktop、java.xml、java.sql、java.naming、java.logging、java.scripting……”订单系统打断道:“等一下,我要导入吗?所有的基本模块?这不累死人吗?”JDK说:“不不不,我也考虑过这个问题。实际上,可以引入隐式依赖。我把JDK中最重要的核心模块组织起来形成一个java.base模块,其他模块都隐式依赖它,就像你的java类不需要扩展Object一样,JDK会自动帮你加上。”4迁移用户系统说:“模块化的思路很好,解决了我的问题。但是现有的大部分程序和jar包都没有实现模块化。自己实现模块化有什么用?你需要谁?谁使用你导出的接口?看,这是一个非常现实的问题。模块化只改JDK是不够的,除非大家都用,否则不会实现。log4j跳出来说:“对对对,你们都迁移到modules了,我又没改,怎么办?”JDK说:“不用担心log4j,肯定有办法让大家慢慢迁移到'modules'的路子就好了,就说你吧,没有模块化,但是用户系统想拥抱模块化,而他想要要求你,我该怎么办?”“也许我可以给他们一个临时名称,比如log4j-module,但是我的模块怎么知道这个‘临时模块’的存在呢?”用户系统说“想想classpath,我们可以建一个modulepath,只要把jar文件加到这个modulepath,比如log4j.jar,就自动认为是一个module(虽然他没有module-info.java语句),因此您可以要求log4j来使用它。”“妙极了,这样可以让大家慢慢迁移,我可以先把我的应用转成模块,如果哪个类库没有拥抱模块化,我就把它放在modulepath里面,让它自动变成模块,这样我就可以require了!“用户系统非常推崇JDK的方式。“不要高兴得太早,”JDK说,“一旦一个类库成为一个自动模块,它就可以访问所有模块,因为我们不知道它依赖于谁。为了让大家迁移到模块化,这也是一个代价。”“对了,如果只有JDK实现了模块化,而我们上层的应用还没有开始迁移,能跑在新的JDK上吗?”订单系统担心的问道。“要能行,不能吹牛,我擅长的一件事就是向后兼容,早期的代码不加修改也能在最新的JRE上运行,新特性不能破坏这种兼容性!”“那怎么办?”““很简单,我会把这些没有迁移的类库全部放到一个叫unnamed的模块里,这样概念就统一了。“不错,听起来可行。”众人纷纷表示赞同:“要不你试试看?”“热豆腐着急吃不下,今天叫你来,就是想跟你分享一下大意,说起来简单,里面也有很多。”细节还得考虑,请耐心等待下个版本的发布!”后记:本文介绍了Java9的新特性:模块化的一些概念,还有很多细节,有兴趣的同学可以点击阅读原文并去openjdk官网看看【本文为专栏作者“刘欣”原创稿件,转载请通过作者微信获得授权公众号coderising】点此查看作者更多好文