[TOC]
# Java 9 PEPK(JShell)
Oracle 公司(Java Library 開發者)新引進一個代表 Java Shell 的稱之為 “jshell” 或者 REPL(Read Evaluate Print Loop)的新工具。該工具可以被用來執行和測試任何 Java 中的結構,如 class,interface,enum,object,statements 等。使用非常簡單。
JDK 9 EA(Early Access)下載地址: https://jdk9.java.net/download/
~~~
G:\>jshell
| Welcome to JShell -- Version 9-ea
| For an introduction type: /help intro
jshell> int a = 10
a ==> 10
jshell> System.out.println("a value = " + a )
a value = 10
~~~
有關 REPL 工具的更多信息,可訪問 [Java 9 REPL Basics (Part-1)](http://www.journaldev.com/9879/java9-install-and-repl-jshell-tutorial) 和 [Java 9 REPL Features (Part-2)](http://www.journaldev.com/12938/javase9-repl-jshell-examples-part2)
# 不可變集合類的工廠方法
Oracle 公司引入一些方便使用的工廠方法,用于創建不可變集合 List,Set,Map 和 Map.Entry 對象。這些高效實用的方法可用來創建空或者非空集合對象。
在 Java SE 8 和更早版本中,我們常用類似 unmodifiableXXX 的集合類方法創建不可變集合對象。舉個例子,比如我們想創建一個不可變的 List 對象,可能使用到 Collections.unmodifiableList 方法。
然而,這些 Collections.unmodifiableXXX 方法顯得非常冗長乏味。為了克服這些缺陷,Oracle 公司給 List、Set 和 Map 接口分別添加了兩個更加實用的方法。
List 和 Set 接口使用 of() 方法創建一個空或者非空的不可變 List 或 Set 對象,如:
空 List 示例
~~~
List immutableList = List.of();
~~~
非空 List 示例
~~~
List immutableList = List.of("one","two","three");
~~~
Map 分別有兩個方法用于創建不可變 Map 對象和不可變 Map.Entry 對象: of() 和 ofEntries() 。
空 Map 示例
~~~
jshell> Map emptyImmutableMap = Map.of()
emptyImmutableMap ==> {}
~~~
非空 Map 示例
~~~
jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")
nonemptyImmutableMap ==> {2=two, 3=three, 1=one}
~~~
更多有關這些實用方法的信息,可以通過這些鏈接查詢:
1. [Java 9 Factory Methods for Immutable List](http://www.journaldev.com/12942/javase9-factory-methods-immutable-list)
2. [Java 9 Factory Methods for Immutable Set](http://www.journaldev.com/12984/javase9-factories-for-immutable-set)
3. [Java 9 Factory Methods for Immutable Map and Map.Entry](http://www.journaldev.com/13057/javase9-factory-methods-immutable-map)
# 接口中的私有方法
在 Java 8 中,我們可以在接口中使用默認或者靜態方法提供一些實現方式,但是不能創建私有方法。
為了避免冗余代碼和提高重用性,Oracle 公司準備在 Java SE 9 接口中引入私有方法。也就是說從 Java SE 9 開始,我們也能夠在接口類中使用 ‘private’ 關鍵字寫私有化方法和私有化靜態方法。
接口中的私有方法與 class 類中的私有方法在寫法上并無差異,如:
~~~
public interface Card{
private Long createCardID(){
// Method implementation goes here.
}
private static void displayCardDetails(){
// Method implementation goes here.
}
}
~~~
有關接口私有方法新特性的更多信息,可訪問我的初體驗之: [Java 9 Private methods in Interface](http://www.journaldev.com/12850/java9-private-methods-in-interface) 。
# Java 9 Module System
Java 9 新特性中最大的一個變化就是 Module System。Oracle 公司將引入如下特性作為 Jigsaw Project 的一部分:
1. Modular JDK
2. Modular Java Source Code
3. Modular Run-time Images
4. Encapsulate Java Internal APIs
5. Java Platform Module System
Java SE 9 版本之前,我們使用 Monolithic Jars 來開發基于 Java 語言的應用程序。這種體系架構有許多局限性和缺點。為了避免這些缺陷,Java SE 9 迎來了 Module System。
JDK 9 包含有 92 個 modules(當然也可能在最終發布版中有所變化)。我們可以使用 JDK Modules,也能創建我們自己的 modules,如:
簡單 Module 示例
~~~
module com.foo.bar { }
~~~
這里我們使用 module 關鍵字創建了一個簡單的 module。每個 module 都有一個名字,對應代碼和其它一些資源。
想了解更多有關這個新體系架構和親自動手體驗的話,可以參考這里我的體驗之:
1. Java 9 Module System Basics
2. Java 9 Module System Examples
# Process API Improvements
Java SE 9 迎來一些 Process API 的改進,通過添加一些新的類和方法來優化系統級進程的管控。
Process API 中的兩個新接口:
1. java.lang.ProcessHandle
2. java.lang.ProcessHandle.Info
Process API 示例
~~~
ProcessHandle currentProcess = ProcessHandle.current();
System.out.println("Current Process Id: = " + currentProcess.getPid());
~~~
# Try With Resources Improvement
我們知道,Java SE 7 引入了一個新的異常處理結構: Try-With-Resources ,來自動管理資源。這個新的聲明結構主要目的是實現“Automatic Better Resource Management”(“自動資源管理”)。
Java SE 9 將對這個聲明作出一些改進來避免一些冗長寫法,同時提高可讀性。
Java SE 7 示例
~~~
void testARM_Before_Java9() throws IOException{
BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
try (BufferedReader reader2 = reader1) {
System.out.println(reader2.readLine());
}
}
~~~
Java SE 9 示例
~~~
void testARM_Java9() throws IOException{
BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
try (reader1) {
System.out.println(reader1.readLine());
}
}
~~~
有關這個特性的更多信息,可以參考我的初體驗之: [Java 9 Try-With-Resources Improvements](http://www.journaldev.com/12940/javase9-try-with-resources-improvements)
# CompletableFuture API Improvements
在 Java SE 9 中,Oracle 公司將改進 CompletableFuture API 來解決一些 Java SE 8 中出現的問題。這些被添加的 API 將用來支持一些延時和超時操作,實用方法和更好的子類化。
~~~
Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);
~~~
這里的 delayedExecutor() 是靜態實用方法,用來返回一個在指定延時時間提交任務到默認執行器的新 Executor 對象。
# Reactive Streams
現在,Reactive Programming 由于其便利性在應用程序開發中變得非常流行。Scala、Play、Akka 等框架已經集成 Reactive Streams 并且受益良多。Oracle 公司也在 Java SE 9 中引入了一個新的 Reactive Streams API。
Java SE 9 Reactive Streams API 是一個發布訂閱型框架,使我們能夠非常簡單地使用 Java 語言就能實現異步的、可拓展的和并行的應用。
Java SE 9 引進下面這些 API 來在基于 Java 語言的應用中開發 Reactive Streams:
1. java.util.concurrent.Flow
2. java.util.concurrent.Flow.Publisher
3. java.util.concurrent.Flow.Subscriber
4. java.util.concurrent.Flow.Processor
# iamond Operator for Anonymous Inner Class
我們知道,Java SE 7 引入了一個新的特性:Diamond Operator,來避免冗長代碼和提升可讀性。然而在 Java SE 8 中,Oracle 公司發現在 Diamond 操作器和匿名內部類的使用中存在一些局限性,后來修復了這些問題并準備將其作為 Java 9 的一部分發布出去。
~~~
public List getEmployee(String empid){
// Code to get Employee details from Data Store
return new List(emp){ };
}
~~~
# Optional Class Improvements
在 Java SE 9 中,Oracle 公司添加了一些新的實用方法到 java.util.Optional 類里面。這里我將使用一些簡單的示例來描述其中的一個:stream 方法。
如果一個值出現在給定 Optional 對象中,stream() 方法可以返回包含該值的一個順序 Stream 對象。否則,將返回一個空 Stream。
stream() 方法已經被添加,并用來在 Optional 對象中使用,如:
~~~
Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)
~~~
這里的 Optional.stream() 方法被用來轉化 Employee 可選流對象 到 Employee 流中,如此我們便可以在后續代碼中使用這個結果。
理解這個特性的更多信息,可參考我的初體驗過程: [Java SE 9: Optional Class Improvements](http://www.journaldev.com/13108/javase9-optional-class-improvements) 。
# Stream API Improvements
在 Java SE 9 中,Oracle 公司添加了四個非常有用的新方法到 java.util.Stream 接口里面。正如 Stream 作為一個接口類,所有這些新的實現方法都是默認方法。其中有兩個方法非常重要:dropWhile 和 takeWhile。
如果你熟悉 Scala 語言或者其它函數編程語言的話,你一定知道這些方法。他們在寫一些功能樣式代碼時非常有用。這里我們一起討論一下 takeWhile 實用方法。
這個 takeWhile() 方法使用一個斷言作為參數,返回給定 Stream 的子集直到斷言語句第一次返回 false。如果第一個值不滿足斷言條件,將返回一個空的 Stream。
~~~
jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 )
.forEach(System.out::println);
1
2
3
4
~~~
更多有關 takeWhile、dropWhile 和其它新方法的信息,可以參考我的初體驗過程之: [Java SE 9: Stream API Improvements](http://www.journaldev.com/13204/javase9-stream-api-improvements) 。
# Enhanced @Deprecated annotation
在 Java SE 8 和更早版本上,@Deprecated 注解只是一個沒有任何方法的標記類接口。它的作用是標記一個 Java API,可以是 calss,field,method,interface,constructor 等。
在 Java SE 9 中,Oracle 公司強化了 @Deprecated 注解,來提供更多有關廢棄 API 的介紹信息,同時也提供一個工具來分析項目中的廢棄 API 的靜態使用情況。Oracle 公司添加了兩個方法到 Deprecated 接口中來提供服務: forRemoval 和 since 。
# HTTP 2 Client
在 Java SE 9 中,Oracle 公司將發布新的 HTTP 2 Client API 來支持 HTTP/2 協議和 WebSocket 特性。現有的 HTTP Client API 存在很多問題(如支持 HTTP/1.1 協議但是不支持 HTTP/2 協議和 WebSocket,僅僅作用在 Blocking 模式中,并存在大量性能問題),他們正在被使用新的 HTTP 客戶端的 HttpURLConnection API 所替代。
Oracle 公司準備在 “java.net.http” 包下引入新的 HTTP 2 Client API。它將同時支持 HTTP/1.1 和 HTTP/2 協議,也同時支持同步(Blocking Mode)和異步模式,支持 WebSocket API 使用中的異步模式。
我們可以在這里查看這個新 API 信息: http://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.html 。
HTTP 2 Client 示例
~~~
jshell> import java.net.http.*
jshell> import static java.net.http.HttpRequest.*
jshell> import static java.net.http.HttpResponse.*
jshell> URI uri = new URI("http://rams4java.blogspot.co.uk/2016/05/java-news.html")
uri ==> http://rams4java.blogspot.co.uk/2016/05/java-news.html
jshell> HttpResponse response = HttpRequest.create(uri).body(noBody()).GET().response()
response ==> java.net.http.HttpResponseImpl@79efed2d
jshell> System.out.println("Response was " + response.body(asString()))
~~~
可以通過我的初體驗之: Java SE 9: HTTP 2 Client ,理解 HTTP/2 協議和 WebSocket,以及使用一些有用的示例對比新 API 的優勢和舊 OLD API 的缺陷。
# Мulti-Resolution Image API
在 Java SE 9 中,Oracle 公司將引入一個新的 Мulti-Resolution Image API。這個 API 中比較重要的接口是 MultiResolutionImage ,在 java.awt.image 包下可獲取到。
MultiResolutionImage 封裝不同高度和寬度圖片(不同解決方案)到一個集合中,并允許我們按需查詢使用。
# Miscellaneous Java 9 Features
在這個部分,我將列出 Java SE 9 新特性中其它一些內容。當然,這并不是這些內容就不重要。使用一些示例去理解他們也是非常重要并且很實用的。
截至目前,我并沒有獲取到這些特性的足夠多信息。這就是為什么我將他們簡單列舉至此的原因。我也會一個一個去獲取信息并采用一些示例來說明這個部分列舉的特性內容。并且會在晚些寫成一個獨立的體驗部分。
1. GC (Garbage Collector) Improvements
2. Stack-Walking API
3. Filter Incoming Serialization Data
4. Deprecate the Applet API
5. Indify String Concatenation
6. Enhanced Method Handles
7. Java Platform Logging API and Service
8. Compact Strings
9. Parser API for Nashorn
10. Javadoc Search
11. HTML5 Javadoc
后面我將逐個搜集這些 java 9 中的特性,并使用足夠的描述性文字和示例代碼予以解釋。
- 基礎
- 編譯和安裝
- scanner類(鍵盤錄入)
- Random類(隨機數)
- 數組
- 方法
- 類
- ArrayList集合
- char與int
- eclipse
- IDEA
- 變量與常量
- 常用API
- String,StringBuffer,StringBuilder
- 正則,Date,DateFormat,Calendar
- 包裝類,System,Math,Arrays,BigInteger,BigDecimal
- 集合,迭代器,增強for,泛型
- List,set,判斷集合唯一
- map,Entry,HashMap,Collections
- 異常
- IO
- File
- 遞歸
- 字節流
- 字符流
- IO流分類
- 轉換流
- 緩沖流
- 流的操作規律
- properties
- 序列化流與反序列化流
- 打印流
- commons-IO
- IO流總結
- 多線程
- 線程池
- 線程安全
- 線程同步
- 死鎖
- lock接口
- ThreadLoad
- 等待喚醒機制
- 線程狀態
- jdbc
- DBUtils
- 連接池DBCP
- c3p0連接池
- 網絡編程
- 多線程socket上傳圖片
- 反射
- xml
- 設計模式
- 裝飾器模式
- web service
- tomcat
- Servlet
- response
- request
- session和cookie
- JSP
- EL
- JSTL
- 事務
- 監聽器Listener
- 過濾器Filter
- json
- linux安裝軟件
- 反射詳解
- 類加載器和注解
- 動態代理
- jedis
- Hibernate
- 簡介
- 創建映射文件
- Hibernate核心配置文件
- 事務和增刪改查
- HibernateUtils
- 持久化對象的三種狀態
- 檢索方式
- query
- Criteria
- SQLQuery
- 持久化類
- 主鍵生成策略
- 緩存
- 事務管理
- 關系映射
- 注解
- 優化
- struts2
- 搭建
- 配置詳解
- Action
- 結果跳轉方式
- 訪問ServletAPI方式
- 如何獲得參數
- OGNL表達式
- valueStack 值棧
- Interceptor攔截器
- spring
- 導包
- IOC和DI
- Bean獲取與實例化
- Bean屬性注入
- spring注解
- 注解分層
- junit整合
- aop
- 動態代理實現
- cglib代理實現
- aop名詞
- spring的aop
- aop-xml詳解
- aop-注解詳解
- 代理方式選擇
- jdbcTemplate
- spring事務管理
- 回滾注意
- 事務傳播屬性
- MyBatis
- MyBatis簡介
- 入門程序
- 與jdbc hibernate不同
- 原始Dao開發
- Mapper動態代理方式
- SqlMapConfig.xml配置文件
- 輸入參數pojo包裝類
- resultMap
- 動態sql
- 一對一關聯
- 一對多
- 整合spring
- 逆向工程
- maven
- maven簡介
- 倉庫
- maven目錄結構
- maven常用命令
- 生命周期
- eclipse中maven插件
- 入門程序
- 整合struct
- 依賴范圍
- 添加插件
- idea配置
- jar包沖突
- 分模塊開發
- 構建可執行的jar包(包含依賴jar包)
- springMVC
- 處理流程
- java面試
- java版本升級
- java1-8版本變更
- java9新特性
- 鎖
- java資料
- idea
- jdk版本切換
- log4j
- 入門實例
- 基本使用方法
- Web中使用Log4j
- spring中使用log4j
- java代碼優化