原文出處: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());