原文出处:wangwenjun69javascript
Java 8 已经出来三年多的时间了,本来计划2016年七月份release Java 9,可是基于种种缘由,Java 9 被推迟到了2017年的3月份,本人也在Open JDK的官网上看到了Java 10的标准也在制定当中,Java的发展真的愈来愈快了,在Java 9正式发布以前,咱们可使用它的SNAPSHOT版本,先来体验一下Java 9 有哪些新的特性,下面的清单来自于官方文档,看着彷佛不少,可是真正具备颠覆意义的其实就是Module System,其他不少主要是一些新的feature增长,还有一些功能的增强,在本篇文章中,咱们将介绍一下主要的几个,不会一一去说,资料也很少,因此我想说也没的说,另外Java 8 是我认为迄今为止Java 最大的一次变化,不光是特性的增长,更多的是编程风格的转变,若是你尚未掌握Java 8,建议你看一下本人录制的教学视频,大体40集,专门是针对Java 8特性的实战视频,下载地址为:java
https://pan.baidu.com/s/1nvCt83vweb
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
该特性是Java 9 最大的一个特性,Java 9起初的代号就叫Jigsaw,最近被更改成Modularity,Modularity提供了相似于OSGI框架的功能,模块之间存在相互的依赖关系,能够导出一个公共的API,而且隐藏实现的细节,Java提供该功能的主要的动机在于,减小内存的开销,咱们你们都知道,在JVM启动的时候,至少会有30~60MB的内存加载,主要缘由是JVM须要加载rt.jar,无论其中的类是否被classloader加载,第一步整个jar都会被JVM加载到内存当中去,模块化能够根据模块的须要加载程序运行须要的class,那么JVM是如何知道须要加载那些class的呢?这就是在Java 9 中引入的一个新的文件module.java咱们大体来看一下一个例子(module-info.java)算法
1 module com.baeldung.java9.modules.car { 2 requires com.baeldung.java9.modules.engines; 3 exports com.baeldung.java9.modules.car.handling; 4 }
关于更多Java 9 模块编程的内容请参考一本书:《Java 9 Modularity》 里面讲的比较详细,介绍了当前Java对jar之间以来的管理是多么的混乱,引入modularity以后的改变会是很明显的差异。shell
就目前而言,JDK提供的Http访问功能,几乎都须要依赖于HttpURLConnection,可是这个类你们在写代码的时候不多使用,咱们通常都会选择Apache的Http Client,这次在Java 9的版本中引入了一个新的package:java.net.http,里面提供了对Http访问很好的支持,不只支持Http1.1并且还支持HTTP2,以及WebSocket,听说性能能够超过Apache HttpClient,Netty,Jetty,简单的来看一个代码片断编程
1 URI httpURI = new URI("http://www.94jiankang.com"); 2 HttpRequest request = HttpRequest.create(httpURI).GET(); 3 HttpResponse response = request.response(); 4 String responseBody = response.body(HttpResponse.asString());
在Java很早的版本中,提供了Process这样的API能够得到进程的一些信息,包括runtime,甚至是用它来执行当前主机的一些命令,可是请你们思考一个问题,你如何得到你当前Java运行程序的PID?很显然经过Process是没法得到的,须要借助于JMX才能获得,可是在这一次的加强中,你将会很轻松的获得这样的信息,咱们来看一个简单的例子json
1 ProcessHandle self = ProcessHandle.current(); 2 long PID = self.getPid(); 3 ProcessHandle.Info procInfo = self.info(); 4 5 Optional<String[]> args = procInfo.arguments(); 6 Optional<String> cmd = procInfo.commandLine(); 7 Optional<Instant> startTime = procInfo.startInstant(); 8 Optional<Duration> cpuUsage = procInfo.totalCpuDuration();
上面有大量的Optional,这是Java 8中的API,一样在Java 9中对其进行了加强,本人在Java 8实战视频中对Optional API进行了源码级别的剖析,感兴趣的必定要去看看。api
已经获取到了JVM的进程,咱们该如何将该进程优雅的停掉呢?下面的代码给出了答案app
1 childProc = ProcessHandle.current().children(); 2 childProc.forEach(procHandle -> { 3 assertTrue("Could not kill process " + procHandle.getPid(), procHandle.destroy()); 4 });
经过上面的一小段代码,咱们也发现了Java 9对断言机制一样增长了一些加强,多说一些题外话,咱们目前的系统中运行一个严重依赖于Hive beelineServer的程序,beeline server不是很稳定,常常出现卡顿,甚至假死,假死后也不回复的问题,这样就致使咱们的程序也会出现卡顿,若是运维人员不对其进行清理,系统运行几个月以后会发现不少僵尸进程,因而增长一个获取当前JVM PID的功能,而后判断到超过给定的时间对其进行主动杀死,彻底是程序内部的行为,可是获取PID就必须借助于JMX的动做,另外杀死它也必须借助于操做系统的命令,诸如kill这样的命令,显得很是的麻烦,可是Java 9的方式明显要优雅方便许多。框架
咱们都知道,Try-With-Resources是从JDK 7 中引入的一项重要特征,只要接口继承了Closable就可使用Try-With-Resources,减小finally语句块的编写,在Java 9 中会更加的方便这一特征
1 MyAutoCloseable mac = new MyAutoCloseable(); 2 try (mac) { 3 // do some stuff with mac 4 } 5 6 try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) { 7 // do some stuff with finalCloseable 8 } catch (Exception ex) { }
咱们的Closeable彻底不用写在try()中。
1 FooClass<Integer> fc = new FooClass<>(1) { // anonymous inner class 2 }; 3 4 FooClass<? extends Integer> fc0 = new FooClass<>(1) { 5 // anonymous inner class 6 }; 7 8 FooClass<?> fc1 = new FooClass<>(1) { // anonymous inner class 9 };
1 interface InterfaceWithPrivateMethods { 2 3 private static String staticPrivate() { 4 return "static private"; 5 } 6 7 private String instancePrivate() { 8 return "instance private"; 9 } 10 11 default void check() { 12 String result = staticPrivate(); 13 InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods() { 14 // anonymous class 15 }; 16 result = pvt.instancePrivate(); 17 } 18 }}
该特性彻底是为了Java 8中default方法和static方法服务的。
在Java 8 出来的时候,不少人都喊着,这是要抢夺Scala等基于JVM动态语言的市场啊,其中有人给出了一个Java作不到的方向,那就是Scala能够看成脚本语言,Java能够么?很明显在此以前Java不行,ta也不具有动态性,可是这次Java 9 却让Java也能够像脚本语言同样来运行了,主要得益于JShell,咱们来看一下这个演示
1 jdk-9\bin>jshell.exe 2 | Welcome to JShell -- Version 9 3 | For an introduction type: /help intro 4 jshell> "This is my long string. I want a part of it".substring(8,19); 5 $5 ==> "my long string"
这是咱们在Jshell这个控制台下运行,咱们如何运行脚本文件呢?
1 jshell> /save c:\develop\JShell_hello_world.txt 2 jshell> /open c:\develop\JShell_hello_world.txt 3 Hello JShell!
记得在Java 8中,放弃了Jhat这个命令,可是很快在Java 9中增长了一些新的命令,好比咱们要介绍到的jcmd,借助它你能够很好的看到类之间的依赖关系
1 jdk-9\bin>jcmd 14056 VM.class_hierarchy -i -s java.net.Socket 2 14056: 3 java.lang.Object/null 4 |--java.net.Socket/null 5 | implements java.io.Closeable/null (declared intf) 6 | implements java.lang.AutoCloseable/null (inherited intf) 7 | |--org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket 8 | | implements java.lang.AutoCloseable/null (inherited intf) 9 | | implements java.io.Closeable/null (inherited intf) 10 | |--javax.net.ssl.SSLSocket/null 11 | | implements java.lang.AutoCloseable/null (inherited intf) 12 | | implements java.io.Closeable/null (inherited intf)
接口java.awt.image.MultiResolutionImage封装了一系列的不一样分辨率图像到一个单独对象的API,我么能够根据给定的DPI 矩阵获取resolution-specific,看一下下面的代码片断
1 BufferedImage[] resolutionVariants = .... 2 MultiResolutionImage bmrImage 3 = new BaseMultiResolutionImage(baseIndex, resolutionVariants); 4 Image testRVImage = bmrImage.getResolutionVariant(16, 16); 5 assertSame("Images should be the same", testRVImage, resolutionVariants[3]);
关于AWT的东西,本人几乎不怎么接触,若是有用到的朋友,等JDK 9出来以后,本身体会使用一下吧。
很早以前就传言Java 会将unsafe这一个类屏蔽掉,不给你们使用,此次看他的官方文档,貌似全部已sun开头的包都将不能在application中使用,可是java 9 提供了新的API供你们使用。
在JDK 9中提供了一个新的包,叫作java.lang.invoke里面有一系列很重要的类好比VarHandler和MethodHandles,提供了相似于原子操做以及Unsafe操做的功能。
在新版的JDK 9 中提供了消息发布订阅的框架,该框架主要是由Flow这个类提供的,他一样会在java.util.concurrent中出现,而且提供了Reactive编程模式。
该特性为JVM的全部组件引入了一个通用的日志系统,提供了JVM日志的基础设施,你能够不用专门为了打印某些日志而添加一些专门的标签,只须要使用统一的log指令便可,好比:
1 java -Xlog:gc=debug:file=gc.txt:none ... 2 jcmd 9615 VM.log output=gc_logs what=gc
其实在Java的早期版本中就已经有这样的功能了,好比Collections.xxx就能够将某个collection封装成不可变,可是这次的Java 9版本将其加到了对应的Set和List中,而且有一个专门的新包用来存放这些具体的实现java.util.ImmutableCollections,这一个特性和Scala真的一模一样。
1 Set<String> strKeySet = Set.of("key1", "key2", "key3");
对Option提供了stream功能,关于Optional的用法,我在个人教程中讲的很是详细,若是你尚未掌握,抓紧啊
1 List<String> filteredList = listOfOptionals.stream() 2 .flatMap(Optional::stream) 3 .collect(Collectors.toList());