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
291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector
292: Implement Selected ECMAScript 6 Features in Nashorn
294: Linux/s390x Port
295: Ahead-of-Time Compilation
297: Unified arm32/arm64 Port
298: Remove Demos and Samples
299: Reorganize Documentation複製程式碼
- 模組化系統
模組化是一個很通用的概念。在軟體中,模組化可以運用到編寫和實現一個程式和計算系統,他們都是作為獨立的模組,而不是作為一個單一的和完整的設計。
Java 9中主要的變化是已經實現的模組化系統。模組化的引入使得JDK可以在更小的裝置中使用。採用模組化系統的應用程式只需要這些應用程式所需的那部分JDK模組,而非是整個JDK框架了。模組化系統也可以將公共的類封裝到一個模組中。因此一個封裝在模組中的定義為public的類不能再任何地方使用,除非一個模組顯式的定義了這個模組。由於Java 9的這個變化,Java內部的API(例如com.sun.*)預設情況下是不能使用的。
所有的模組將需要在module-ionfo.java檔案中進行描述,該檔案位於Java程式碼結構的頂層。
module me.aboullaite.java9.modules.car {
requires me.aboullaite.java9.modules.engines;//依賴的模組
exports me.aboullaite.java9.modules.car.handling;//在模組中匯出的包
}複製程式碼
我們的模組car(汽車)需要依賴+模組engine(引擎)和需要匯出handling(操作)包。
更多例子可以檢視OpenJDK中專案Jigsaw:模組化系統快速入門
- JShell–Java 9 REPL
REPL是一種快速執行語句的命令列工具。
在Java中,如果你想執行一個簡單的語句,我們要麼建立一個帶main方法的類,要麼建立一個可以執行的Test類。當你正在啟動Java程式的時候,如果你想執行某些語句並且想立刻看見執行結果,上面的做法看起來不是那麼有用了。(更像python執行程式命令列的模式...)
JShell試圖去解決這個問題。Java開發者可以利用JShell在沒有建立類的情況下直接宣告變數,計算表示式,執行語句。JShell也可以從檔案中載入語句或者將語句儲存到檔案中。並且JShell也可以是tab鍵進行自動補全的特性。
- 集合工廠方法
在Java 9之前,Java只能利用一些實用方法(例如:Collections.unmodifiableCollection(Collection<? extends T> c))建立一個不可修改檢視的集合。例如,我們可以在Java 8中使用一條如下所示的語句,建立一個Collection的不可修改的檢視。雖然這是最簡單的建立方式,但是看起來很糟糕!不是嗎?
Map<String,String> immutableMap =
Collections.unmodifiableMap(
new HashMap<String,String>(){
{
put("key1","value1");
put("key2","value2");
put("key3","value3");
}
});複製程式碼
在Java9中引入了一些有用的工廠方法來建立不可修改的集合:
Map<String,String> immutableMap = Map.of("key1","value1","key2","value2","key3","value3");複製程式碼
工廠方法的例子如下:
//不可修改的空集合
List<String> emptyImmutableList = List.of();
Set<String> emptyImmutableSet = Set.of();
Map emptyImmutableMap = Map.of();
//不可修改的集合
List<String> immutableList = List.of("one","two");
Set<String> immutableSet = Set.of("value1","value2");
Map<String,String> immutableMap = Map.of("key1","value1","key2","value2","key3","value3");複製程式碼
- 介面中的私有方法
Java 8的介面引入了預設方法和靜態方法。雖然Java 8首次計劃實現介面的私有方法,在Java 9中實現。預設方法和靜態方法可以共享介面中的私有方法,因此避免了程式碼冗餘,這也使程式碼更加清晰。如果私有方法是靜態的,那這個方法就屬於這個介面的。並且沒有靜態的私有方法只能被在介面中的例項呼叫。
interface InterfaceWithPrivateMethods{
private static String staticPrivate(){
return "static private";
}
private String instancePrivate(){
return "instance private";
}
default void check(){
String result = staticPrivate();
InterfaceWithPrivateMethods p = new InterfaceWithPrivateMethods(){
//匿名類
};
result = p.instancePrivate();
}
}複製程式碼
- 響應式流
JDK9中的Flow API對應響應式流規範,響應式流規範是一種事實標準。JEP 266包含了一組最小介面集合,這組介面能捕獲核心的非同步釋出與訂閱。
java.util.concurrent.Flow包含以下4個介面:
Flow.Processor(處理器)
Flow.Publisher(釋出者)
Flow.Subscriber(訂閱者)
Flow.Subscription(訂閱管理器)
這些介面都支援響應式流釋出-訂閱框架。Java 9也提供了實用類SubmissionPublisher。一個釋出者產生一個或多個物品,這些物品由一個或多個消費者消耗。並且訂閱者由訂閱管理器管理。訂閱管理器連線釋出者和訂閱者。
- 多解析度影象API–JEP 251
目標是定義多解析度影象API,這樣開發者就能很容易的操作和展示不同解析度的影象了。這個新的API定義在java.awt.image包中,這個API能給我們帶來如下的幫助:
將不同解析度的影象封裝到一張(多解析度的)影象中,作為它的變體。
獲取這個影象的所有變體。
獲取特定解析度的影象變體–表示一張已知解析度單位為DPI的特定尺寸大小的邏輯影象,並且這張影象是最佳的變體。
基於當前螢幕解析度大小和運用的影象轉換演算法,java.awt.Graphics類可以從介面MultiResolutionImage獲取所需的變體。
java.awt.image.AbstractMultiResolutionImage類提供了java.awt.image.AbstractMultiResolutionImage 預設實現。
AbstractMultiResolutionImage的基礎實現是java.awt.image.BaseMultiResolutionImage。
- 程式API的改進
加入了用來控制和管理作業系統的程式的API,在Java9中,期望程式碼能獲取LINUX PID
在以前的版本中的方法:
public static void main(String[] args) throws Exception{
Process proc = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c","echo $PPID"});
if(proc.waitFor() == 0){
InputStream in = proc.getInputStream();
int available = in.available();
byte[] outputBytes = new byte[available];
in.read(outputBytes);
String pid = new String(outputBytes);
System.out.println("你的PID是:"+pid);
}
}複製程式碼
在java9中變換為如下的方式(同樣支援所有的作業系統):
System.out.println("你的PID是:" + Process.getCurrentPid());複製程式碼
- 異常的處理
在Java 7中,try-with-resouces語法要求為每一個資源宣告一個新的變數,而且這些資源由try-with-resources語句進行管理。
在Java 9中:如果一個資源被final或者等效於final變數引用,則在不需要宣告一個新的變數的情況下,try-with-resources就可以管理這個資源。
MyAutoCloseable mac = new MyAutoCloseable();
try(mac){
//do some stuff with mac
}
try(new MyAutoCloseable(){}.finalWrapper.finalCloseable){
//do some stuff with finalCloseable
}
- diamond操作符範圍的延伸
Java 7給出的鑽石操作符使我們編寫程式碼更簡單了。在下面的例子中,你可以看見Java 7中List的可讀性更強了,但是Java 7中鑽石操作符不允許在匿名類上使用,但在Java 9中改善了這一情況,允許鑽石操作符在匿名類上使用。下面的例子只有在Java 9中才能通過編譯。
List<String> list = new ArrayList<>(){};複製程式碼
- 增強的註釋Deprecated
註釋@Deprecated可以標記Java API。註釋@Deprecated有很多種含義,例如它可以表示在不遠的將來的某個時間,被標記的API將會被移除。它也可以表示這個API已經被破壞了,並不應該再被使用。它還有其它很多含義。為了提供更多有關@Deprecated的資訊,@Deprecated新增了forRemoval元素和since元素。
Java SE 9 中也提供了掃描jar檔案的工具jdeprscan。這款工具也可以掃描一個聚合類,這個類使用了Java SE中的已廢棄的API元素。 這個工具將會對使用已經編譯好的庫的應用程式有幫助,這樣使用者就不知道這個已經編譯好的庫中使用了那些已廢棄的API。
- 統一的JVM日誌
我們很難知道導致JVM效能問題和導致JVM崩潰的根本原因。解決這個問題的一個方法是對所有的JVM元件引入一個單一的系統,這些JVM元件支援細粒度的和易配置的JVM日誌。目前,不同的JVM元件對於日誌使用的是不同的機制和規則,這使得JVM難以進行除錯。
- 註釋@SafeVarargs範圍的延伸
直到Java 8,@SafeVarargs才能在靜態方法、final方法和構造器上使用。但是這些方法或者構造器是不能被覆蓋的。這些方法中缺少另一個不能被覆蓋的方法,這個方法就是私有方法。Java 9可以將@SafeVarargs新增到私有方法上。下面的例子在Java 9中是正確的,但是在Java 8中就會丟擲編譯時錯誤: 註釋@SafeVarargs不能在非final的例項方法iAmSafeVaragrsMethod上使用。
@SafeVarargs
private void iAmSafeVaragrsMethod(String... varagrgs){
for(String each : varagrgs){
System.out.println(each);
}
}複製程式碼
- HTTP 2 客戶端
Java 9採用了全新的HTTP客戶端API,這些API支援HTTP/2協議和WebSocket協議,並且替換了遺留的HTTPURLConnectionAPI。這些改變並不應該在Java 9中完成。這些API可以從Incubator(孵化器)模組中獲取。因此在預設情況下,這個模組是不能根據classpath獲取的,需要使用--add-modules命令選項配置這個模組,將這個模組新增到classpath中。
建立一個HTTP Request請求和獲取非同步的響應:
URI testPageURI = new URI("http://127.0.0.1:8080/testPage");
CompletableFuture<HttpResponse> nonBlockingResponse = HttpRequest
.create(testPageURI)
.GET().responseAsync();
int tries = 0;
while(!nonBlockingResponse.isDone() && tries++ < 5){
Thread.sleep(5);
}
if(nonBlockingResponse.isDone()){
HttpResponse response = nonBlockingResponse.get();
System.out.println("satus code :"+response.statusCode()+"-->"+response.body(HttpResponse.asString()));
}else{
nonBlockingResponse.cancel(true);
System.out.println("cancelling,could not get response");
}複製程式碼
- HTML5風格的Java幫助文件
Java 8以及之前的版本生成的Java幫助文件是在HTML 4中,而HTML 4已經是很久的標準了。在Java 9中,javadoc命令列中選項部分新增了輸出選項,這個選項的值要麼是HTML 4,要麼是HTML 5。現在HTML 4是預設的輸出標記語言,但是在之後釋出的JDK中,HTML 5將會是預設的輸出標記語言。Java幫助文件還是由三個框架組成的結構構成,這是不會變的,並且以HTML 5輸出的Java幫助文件也保持相同的結構。
- 其他的特性
1. 保留下劃線字元。變數不能被命名為_;
2. 廢棄Applet API;
3. javac不再支援Java1.4以及之前的版本;
4. 廢棄Java瀏覽器外掛;
5. 棧遍歷API–棧遍歷API能過濾和遲訪問在堆疊跟蹤中的資訊。複製程式碼