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);
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 模块类或接口来源的信息。
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
AdaptiveSizePausePolicy (自适应大小暂停策略)
CodeCacheMinimumFreeSpace(代码缓存最小空闲空间)
DefaultThreadPriority(默认线程优先级)
JNIDetachReleasesMonitors(JNI分离释放监视器)
LazyBootClassLoader(惰性类启动器)
NmethodSweepCheckInterval(N方法扫描检查间隔)
NmethodSweepFraction(N方法扫描片段)
PrintOopAddress(打印OOP地址)
ReflectionWrapResolutionErrors(反射包装处理错误)
StarvationMonitorInterval(饥饿监视间隔)
ThreadSafetyMargin(线程安全边界)
UseAltSigs(使用alt信号)
UseBoundThreads(使用绑定线程)
UseCompilerSafepoints(使用编译器安全点)
UseFastAccessorMethods(使用快速访问方法)
UseFastEmptyMethods(使用快速空方法)
BackEdgeThreshold(后边缘阈值)
PreInflateSpin(预浸旋转)
20.以下是在 JDK 9 中不再工作的 50 个选项列表。检查下你是否在命令行和启动脚本中使用了这些选项。
AdjustConcurrency
CMSCompactWhenClearAllSoftRefs
CMSDumpAtPromotionFailure
CMSFullGCsBeforeCompaction
CMSIncrementalDutyCycle
CMSIncrementalDutyCycleMin
CMSIncrementalMode
CMSIncrementalOffset
CMSIncrementalPacing
CMSParPromoteBlocksToClaim
CMSPrintEdenSurvivorChunks
CollectGen0First
GCLogFileSize
NumberOfGCLogFiles
ParallelGCVerbose
PrintAdaptiveSizePolicy
PrintCMSInitiationStatistics
PrintCMSStatistics
PrintClassHistogramAfterFullGC
PrintClassHistogramBeforeFullGC
PrintFLSCensus
PrintFLSStatistics
PrintGCApplicationConcurrentTime
PrintGCApplicationStoppedTime
PrintGCCause
PrintGCDateStamps
PrintGCTaskTimeStamps
PrintGCTimeStamps
PrintHeapAtGC
PrintHeapAtGCExtended
PrintJNIGCStalls
PrintOldPLAB
PrintPLAB
PrintParallelOldGCPhaseTimes
PrintPromotionFailure
PrintReferenceGC
PrintTLAB
PrintTenuringDistribution
TraceDynamicGCThreads
TraceGen0Time
TraceGen1Time
TraceMetadataHumongousAllocation
TraceParallelOldGCTasks
UseCMSCollectionPassing
UseCMSCompactAtFullCollection
UseGCLogFileRotation
UseMemSetInBOT
UsePPCLWSYNC
UseVMInterruptibleIO
WorkAroundNPTLTimedWaitHang
以下是jdk9特性标题可自行研究:
102: Process API Updates
110: HTTP 2 Client
143: Improve Contended Locking
158: Unified JVM Logging
165: Compiler Control
193: Variable Handles
197: Segmented Code Cache
199: Smart Java Compilation, Phase Two
200: The Modular JDK
201: Modular Source Code
211: Elide Deprecation Warnings on Import Statements
212: Resolve Lint and Doclint Warnings
213: Milling Project Coin
214: Remove GC Combinations Deprecated in JDK 8
215: Tiered Attribution for javac
216: Process Import Statements Correctly
217: Annotations Pipeline 2.0
219: Datagram Transport Layer Security (DTLS)
220: Modular Run-Time Images
221: Simplified Doclet API
222: jshell: The Java Shell (Read-Eval-Print Loop)
223: New Version-String Scheme
224: HTML5 Javadoc
225: Javadoc Search
226: UTF-8 Property Files
227: Unicode 7.0
228: Add More Diagnostic Commands
229: Create PKCS12 Keystores by Default
231: Remove Launch-Time JRE Version Selection
232: Improve Secure Application Performance
233: Generate Run-Time Compiler Tests Automatically
235: Test Class-File Attributes Generated by javac
236: Parser API for Nashorn
237: Linux/AArch64 Port
238: Multi-Release JAR Files
240: Remove the JVM TI hprof Agent
241: Remove the jhat Tool
243: Java-Level JVM Compiler Interface
244: TLS Application-Layer Protocol Negotiation Extension
245: Validate JVM Command-Line Flag Arguments
246: Leverage CPU Instructions for GHASH and RSA
247: Compile for Older Platform Versions
248: Make G1 the Default Garbage Collector
249: OCSP Stapling for TLS
250: Store Interned Strings in CDS Archives
251: Multi-Resolution Images
252: Use CLDR Locale Data by Default
253: Prepare JavaFX UI Controls & CSS APIs for Modularization
254: Compact Strings
255: Merge Selected Xerces 2.11.0 Updates into JAXP
256: BeanInfo Annotations
257: Update JavaFX/Media to Newer Version of GStreamer
258: HarfBuzz Font-Layout Engine
259: Stack-Walking API
260: Encapsulate Most Internal APIs
261: Module System
262: TIFF Image I/O
263: HiDPI Graphics on Windows and Linux
264: Platform Logging API and Service
265: Marlin Graphics Renderer
266: More Concurrency Updates
267: Unicode 8.0
268: XML Catalogs
269: Convenience Factory Methods for Collections
270: Reserved Stack Areas for Critical Sections
271: Unified GC Logging
272: Platform-Specific Desktop Features
273: DRBG-Based SecureRandom Implementations
274: Enhanced Method Handles
275: Modular Java Application Packaging
276: Dynamic Linking of Language-Defined Object Models
277: Enhanced Deprecation
278: Additional Tests for Humongous Objects in G1
279: Improve Test-Failure Troubleshooting
280: Indify String Concatenation
281: HotSpot C++ Unit-Test Framework
282: jlink: The Java Linker
283: Enable GTK 3 on Linux
284: New HotSpot Build System
285: Spin-Wait Hints
287: SHA-3 Hash Algorithms
288: Disable SHA-1 Certificates
289: Deprecate the Applet API
290: Filter Incoming Serialization Data
292: Implement Selected ECMAScript 6 Features in Nashorn
294: Linux/s390x Port
295: Ahead-of-Time Compilation
总结:个人觉得jdk9是一个分割线,如果想使用的话,那么不止要IDE工具的编写问题,jar包的引用问题,module的引用问题,jvm参数配置问题等等一系列的东西,还有系统重构的大刀阔斧的改变,估计这会使得%60以上的互联网公司放弃使用9导致的公司高成本项目重构,而继续使用jdk8,也会使更多的程序猿们想进入各大前沿公司的台阶进一步的提高,估计又一次的技术革命又快来到了,努力吧少年~~