参考地址:http://openjdk.java.net/projects/jigsaw/
前言
很多朋友可能觉得java9都还没有整明白,java10就出来取代java9了,java11在官网上也已经提上日程了,那我们还有需要学习java9么?
有,当然有,因为无论怎么变,它的开发核心思想是不会变的,就好像我们的标准模块化系统,模块化系统可谓是java的一个重大突破,他的存在使java的运行速度有了一个质的飞跃.并且即使java版本怎么变,这个java的模块系统这一特性是不会变的,从新出的java10就可以体现了,java10依然沿用了这个标准模块化系统.所以现在你们想要用java9,java10甚至是以后的java版本这个标准模块化系统的学习是必须的.那到底标准模块化系统到底是什么东西,他和之前的java版本区别在呢!我们将在本文中掀开他的面纱.
1. 标准模块化系统存在的意义
虽然jdk版本升级了,但是还是有的人在使用旧的版本,为了兼容旧版本的内容,我们不能把旧的东西丢弃,可是新的东西又越来越多,导致jdk越来越臃肿,越来越大,就像一个胖子一样,可是在运行的时候所有的内容都要加载进去内存中,导致了加载时间变长,运行速度变慢,为了改变这样一个问题,提出了模块独立、化繁为简的设计理念,从此Jigsaw项目由此诞生.
Jigsaw项目分为Java SE平台设计和实现标准模块系统两个内容,也就是说模块化系统只是Jigsaw项目的一部分。其主要目标是为了让我们的java平台的实现更容易扩展到小型设备,提高安全性和可维护性,提高应用程序性能,并为开发人员提供更好的大型编程工具。
2. 与之前的版本相比,jdk的改变.
安装目录的改变:
通过安装目录我们可以知道java9做出了一个洗牌性的改变:
1.jre文件夹没有了,jre文件夾包含rt.jar类库等,jre里面包含了我们java的运行环境和jvm,他被jmods文件夹取代了
2.lib中删掉了tools.jar,tools.jar中存放的是javac编译器等工具类库.
3.还有一个新的conf 目录,可以让管理员更改 JDK 配置. Conf 中有网络和日志属性。
那些改变是和标准模块化系统相关的呢?
Java8以及之前版本的jdk在jvm启动的时候都需要把所有的jar包通过classloader加载进内存,不管你是否用到都加载进内存,所以内存需要消耗120MB左右,如果不改变这种加载方式,这个占的内存空间会随着版本的更新而增加.
java9改变了之后,它把必须加载的jre中的jar包转换成jmods一个个的jmod文件了,而这些jmod文件是可选的,系统会默认一个java.base.jmod文件,其余的我们可以根据自己的需求进行一个配置,系统会根据我们的配置进行一个加载,这样更好的贴合我们的要求,改变了之后我们的内存要求就大大的减少了只需要2-120MB内存,这样做到了因地制宜,我们就可以让java使用在一些内存比较小的设备中了,甚至可以使用在现在非常流行的物联网的应用,让java这个语言的使用更为广泛.
没有了tools.jar这些jar包,classpath的配置都变得没有意义了,解决了很多关于classpath配的问题.类的引用都是通过module-info.java文件进行的,清晰明了可维护性更加高.模块与模块之间还需要配置关系,所以现在类与类之间的访问不再是单单根据访问权限来了,即使你的类使用了public,如果模块和模块之间没有进行依赖也是访问不了的,提高了访问的安全性实现了强封装.
3. 类加载机制的变化
Jar包变为jmod模块,可想而知类的加载机制也会发生改变
通过类加载机制的类关系图可以发现,java8和java9最大的不同在于ExtClassLoader变成了PlatformClassLoader加载器.
我们现在先来一起了解一下这些加载类的作用吧!
Java8的类加载类:
Bootstrp loader:启动类加载器,负责加载%JAVA_HOME%/jre/lib目录下的类库,如rt.jar,为什么上面类关系图中没有显示这个类呢,因为BootClassLoader这个类是C++语言写的,所以我们不能直接引用.
ExtClassLoader:扩展类加载器,负责加载%JAVA_HOME%/jre/lib/ext目录的类库
AppClassLoader:应用程序类加载器,负责加载系统类路径classpath目录下的类库
三者的加载机制模型关系图如下:
这种模型叫做双亲委托模型,其实就是当我们写的自定义类需要加载,那么这个是我们自己写的程序,是需要AppClassLoader来加载的,但是在AppClassLoader加载之前他先会委托给ExtClassLoader看看%JAVA_HOME%/jre/lib/ext目录中有没有这个类,那么此时ExtClassLoader还会先委托给Bootstrp loader先查%JAVA_HOME%/jre/lib目录下有没有这个类.这样一级一级地确认自定义类是唯一的,这样的加载方式就是双亲委托加载机制.
目的是为了能够防止重复加载.
Java9的类加载类:
BootClassLoader:启动类加载器,加载启动的基础模块类,例如: java.base、java.logging 、java.desktop等模块.
PlatformClassLoader:加载平台相关的模块,例如:java.activation 、java.se 、jdk.desktop等模块
AppClassLoader:加载应用级别的模块,例如: jdk.javadoc 、 jdk.jshell 、 jdk.jlink 等模块
三者的加载机制模型关系图如下:
Java9还是双亲委托模型,这是没毛病的,这样做的目的还是和之前的版本兼容,但是它在之前的基础上多加了一层,就是加载自定类,还是通过AppClassLoader加载,
AppClassLoader先查找BootClassLoader和PlatformClassLoader中我们配置的模块中有没有,找了模块之后如果还是找不到的话就证明这些类可能不在模块中,所以还是按照旧的加载方式先找PlatformClassLoader对应目录中的类,没有找到再去找BootClassLoader中对应的类.
PlatformClassLoader也是一样的,所有加载器配置模块中找到对应的类,找不到再去找BootClassLoader对应的目录中的类.
BootClassLoader就只需要从自己的模块中找,模块找不到再找自己目录中的类.
也就是先加载模块中的类再找目录下的类
小结:
本文讲述了标准模块化系统对java的好处和加载机制和之前版本的一个区别,但是具体的怎么用我们还没有去实现,请期待下一篇文章,下一篇文章我们将带大家使用模块化系统来开发,真正通过代码来感受其强大之处.