JDK9特性

1.modularity System 模块系统
个人理解:在包结构上层加入module来更好的控制访问权限,从以往全公开jar改为半公开jar;
减少不必要的classLoader执行,以减少JVM的内存占用,从而提高启动、运行速度;
Modularity提供了类似于OSGI框架的功能,模块之间存在相互的依赖关系,可以导出一个公共的API,并且隐藏实现的细节,Java提供该功能的主要的动机在于,减少内存的开销,在JVM启动的时候,至少会有30~60MB的内存加载,主要原因是JVM需要加载rt.jar,不管其中的类是否被classloader加载,第一步整个jar都会被JVM加载到内存当中去,模块化可以根据模块的需要加载程序运行需要的class。
在引入了模块系统之后,JDK 被重新组织成 94 个模块。Java 应用可以通过新增的 jlink 工具,创建出只包含所依赖的 JDK 模块的自定义运行时镜像。这样可以极大的减少 Java 运行时环境的大小。使得JDK可以在更小的设备中使用。采用模块化系统的应用程序只需要这些应用程序所需的那部分JDK模块,而非是整个JDK框架了。
详情介绍:专业版(没有很好的基础或者理解能力不是很好的同学不建议看这个):
https://blog.csdn.net/houxuehan/article/details/78549711?locationNum=8&fps=1
易懂版(简单介绍初步使用和基础特点,深入部分需要自行翻阅资料):
https://blog.csdn.net/rickiyeat/article/details/78071385
模块化详细版(想要深入理解的同学可以参考理解):
https://segmentfault.com/a/1190000009960383
2.HTTP/2 http协议2.0版本:
个人理解:主要特性就是一次请求多次相应,一些频繁与用户交互的应用会用的比较多;
https://blog.csdn.net/yongqi_wang/article/details/82019648
3.JShell 使用window server的形式进行本地执行(你们的小黑窗又回来了)
个人理解:没发现又什么很大的作用,也可能是由于新出来的,所以功能没有感觉多强大;
优点:使用cmd直接进行编译java代码,可以直接输出运行结果。也可以设置使用其他的文本编译进行导入
缺点:只能导入jdk中包,自定义的需要导入加载很麻烦,搞不懂应用场景在哪里,是在嘲讽会写java的没有一个好用的IDE工具?;
具体使用自行摸索吧,安装好jdk9后,打开cmd直接输入jshell 就可以进入编译模式 ,也可以到jdk安装目录/bin中找到jshell.exe双击运行;
基础使用教程:https://blog.csdn.net/songhongk/article/details/78997580
4.不可变集合工厂方法
Java 9增加了List.of()、Set.of()、Map.of()和Map.ofEntries()等工厂方法来创建不可变集合。

List strs = List.of("Hello", "World");
List strs List.of(1, 2, 3);
【JDK9特性】Set strs = Set.of("Hello", "World");
Set ints = Set.of(1, 2, 3);
Map maps = Map.of("Hello", 1, "World", 2);
除了更短和更好阅读之外,这些方法也可以避免您选择特定的集合实现。在创建后,继续添加元素到这些集合会导致 “UnsupportedOperationException” 。
5.私有接口方法
Java 8 为我们提供了接口的默认方法和静态方法,接口也可以包含行为,而不仅仅是方法定义。(使用default修饰的方法可以在接口中实现,而不是只能声明);
Java9中对接口进行了第二次的扩展,默认方法和静态方法可以共享接口中的私有方法,因此避免了代码冗余,这也使代码更加清晰。如果私有方法是静态的,那这个方法就属于这个接口的。并且没有静态的私有方法只能被在接口中的实例调用。
6.HTML5风格的Java帮助文档
Java 8之前的版本生成的Java帮助文档是在HTML 4中。在Java 9中,Javadoc 的输出现在符合兼容 HTML5 标准。
现在HTML 4是默认的输出标记语言,但是在之后发布的JDK中,HTML 5将会是默认的输出标记语言。
Java帮助文档还是由三个框架组成的结构构成,这是不会变的,并且以HTML 5输出的Java帮助文档也保持相同的结构。
每个 Javadoc 页面都包含有关 JDK 模块类或接口来源的信息。
JDK9特性
文章图片

7.多版本兼容 JAR
当一个新版本的 Java 出现的时候,你的库用户要花费很长时间才会切换到这个新的版本。这就意味着库要去向后兼容你想要支持的最老的 Java 版本 (许多情况下就是 Java 6 或者 7)。这实际上意味着未来的很长一段时间,你都不能在库中运用 Java 9 所提供的新特性。幸运的是,多版本兼容 JAR 功能能让你创建仅在特定版本的 Java 环境中运行库程序时选择使用的 class 版本:
8.统一 JVM 日志
Java 9 中 ,JVM 有了统一的日志记录系统,可以使用新的命令行选项-Xlog 来控制 JVM 上 所有组件的日志记录。该日志记录系统可以设置输出的日志消息的标签、级别、修饰符和输出目标等。
9.java9的垃圾收集机制
Java 9 移除了在 Java 8 中 被废弃的垃圾回收器配置组合,同时把G1设为默认的垃圾回收器实现。替代了之前默认使用的Parallel GC,对于这个改变,evens的评论是酱紫的:这项变更是很重要的,因为相对于Parallel来说,G1会在应用线程上做更多的事情,而Parallel几乎没有在应用线程上做任何事情,它基本上完全依赖GC线程完成所有的内存管理。这意味着切换到G1将会为应用线程带来额外的工作,从而直接影响到应用的性能
10.I/O 流新特性
java.io.InputStream 中增加了新的方法来读取和复制 InputStream 中包含的数据。
readAllBytes:读取 InputStream 中的所有剩余字节。
readNBytes: 从 InputStream 中读取指定数量的字节到数组中。
transferTo:读取 InputStream 中的全部字节并写入到指定的 OutputStream 中 。
以上部分基于https://blog.csdn.net/mxw2552261/article/details/79080678修改,添加了一些自己理解的部分和更多人的链接,帮助大家更好的理解学习
以下部分基于https://blog.csdn.net/Cafuf/article/details/78036925修改,添加了一些自己理解的部分
11.标识符
jdk8及之前版本中下划线一直被用于命名过程中多个单词的链接,或者一个变量名,jdk9中单个下划线被声明成为了一个关键字,可以使用在拉达姆表达式中。例如: _ -> foo();其余用途请自行摸索。
12.由于模块化的使用导致JDK 的布局发生了变化 (JEP 220): 如果你依赖于 $ JAVA_HOME 中特定的文件,你可能需要做一些更改。

  • 不再有单独的 jre,bin,lib 等子目录。 JDK 目录结构现在与单个 bin 目录平行(因此只有一个 Java 可执行文件的副本),lib 目录用于本机库和 JDK 模块的 jmods 目录。还有一个新的 conf 目录,可以让管理员更改 JDK 配置。Conf 中有网络和日志属性。
  • 这个转变意味着不再有 rt.jar 或 tools.jar 文件。你需要更改代码来访问这些文件。
  • hprof 代理已从JDK 9(JEP 240)中删除,因此 lib / libhprof.so(或 Windows 上的 bin / hprof.dll )文件也被删除。
13.JDK 版本字符串(JEP 223):
老的定义 JDK 版本的方法相当混乱。例如,我们有 JDK 8u131 ,但是如果你运行 java -version ,你会得到 java version "1.8.0_131" 。
为了从人类和应用程序角度简化这个(定义版本的方法),现在的版本格式是 JDK $MAJOR.$MINOR.$SECURITY.$PATCH ,所以在 JDK9 上的 java -version 将返回 java version "9"(一旦发布最终的 release 版,我们获取更新之后该版本号就会改动)。这里重要的是,如果你在代码中使用 JVM 的版本字符串,并依赖于当前版本格式,那么在 JDK 9 中你必须进行代码改动才能正确运行。
14.线程Thread的stop方法重载
Thread.stop(Throwable) 现在会抛出一个 UnsupportedOperationException ,它之前并没有抛出类似异常。
由于其自身缺乏线程安全性,因此不推荐使用此方法。另一个不带参数的 Thread.stop() 版本仍然可以使用,并且不会抛出异常(但仍然不推荐使用,并强烈建议不要使用此函数)
15. Java 网络登录协议(Java Network Launch Protocol ,JNLP)已更新,以支持严格的配置文件解析。现在使用的格式符合 XML 规范,要求“&”版本范围连接器表示为“& ”。
配置解析目前是严格的,这意味着一些在旧版本的 Java 中可以使用的文件现在将会产生错误。 有关更多详细信息,请参见JSR 52维护页面。
16.与 JPMS 相关的扩展机制(可选软件包)和已批准的标准覆盖机制都已被删除,并使用 JPMS 对应物替代。
因此,$JAVA_HOME/lib/ext 和 $JAVA_HOME/lib/endorsed 的目录已被删除。如果你重新创建这些目录,并尝试把东西放在这些目录下,祈祷他们能工作,这是不可能的。JVM 在查找到这些目录时将无法启动,你将收到以下错误消息:
/lib/ext exists, extensions mechanism no longer supported; Use -classpath instead.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
17.六个之前已弃用的公共方法已经被删除。这是一件相当大的事情,因为这些是 Java 历史上第一次要删除的API。
已删除的方法包括
java.util.jar.Pack200
java.util.jar.Unpack200中的
addPropertyChangeListener()
removePropertyChangeListener()
以及 java.util.logging.LogManager类。
com.sun.security.auth.callback.DialogCallbackHandler 类已被删除(JAAS,Java授权认证服务的一部分的)
(Java Authentication and Authorization Service)
再次建议大家如果发现是用的方法已经过期一定要及时修改,万一哪天做升级时才发现有N多要修改的地方,哭都来不及;
18.JRE 版本选择将不再可用。过去有两种做法可以实现 JRE 版本选择。第一个是在命令行中使用 -version: 选项
如果使用该选项,JVM 将中止而不再启动。第二种方式是从 jar 文件的 manifest 。在这种情况下,JDK 9 将忽略该指令,但会正常启动。有人觉得,与改变命令行相比,强迫人们改变 manifest 太麻烦了。请注意,-version 选项(不带后面的冒号和版本号)仍然可以报告你所使用的 Java 运行时版本。
也就是说以后安了9就只能爱它一个,不允许你在三妻四妾了。
19.由于GC的默认实现类被替换为G1,所以废弃的GC选项已被移除
这些将不会被识别,并将导致 JVM 在启动时中止。要注意的选项如下所示
-XX:-UseParNewGC -XX:+UseConcMarkSweepGC
-XX:+UseParNewGC
-Xincgc
-XX:+CMSIncrementalMode -XX:+UseConcMarkSweepGC
-XX:+CMSIncrementalMode -XX:+UseConcMarkSweepGC -XX:-UseParNewGC
-XX:+UseCMSCompactAtFullCollection
-XX:+CMSFullGCsBeforeCompaction
-XX:+UseCMSCollectionPassing
对 -XX 选项的更改可以分为三组:
已忽略的命令行选项
如果使用其中的一个,您将收到以下警告消息,但 JVM 将正常启动。
Java HotSpot(TM) 64-Bit Server VM warning: Ignoring option