精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
java9新特性(簡述十大新特性)

經過4次跳票,歷經曲折的java 9 終于終于在2017年9月21日發布(距離上個版本足足3年半時間)

java 9 提供了超過 150 項新功能特性,包括備受期待的模塊化系統、可交互的 REPL 工具:jshell,JDK 編譯工具,Java 公共 API 和私有代碼,以及安全增強、擴展提升、性能管理改善等。可以說 Java 9 是一個龐大的系統工程,完全做了一個整體改變。但本博文只介紹最重要的十大新特性

特性列表

  • 平臺級modularity(原名:Jigsaw) 模塊化系統
  • Java 的 REPL 工具: jShell 命令
  • 多版本兼容 jar 包(這個在處理向下兼容方面,非常好用)
  • 語法改進:接口的私有方法
  • 語法改進:UnderScore(下劃線)使用的限制
  • 底層結構:String 存儲結構變更(這個很重要)
  • 集合工廠方法:快速創建只讀集合
  • 增強的 Stream API
  • 全新的 HTTP 客戶端 API
  • 其它特性

它的新特性來自于100于項JEP和40于項JSR

1. 平臺級modularity(原名:Jigsaw) 模塊化系統

模塊化系統Java7開始籌備,Java8進行了大量工作,Java9才落地。首先帶來最直觀的感受,就是目錄結構的感受:
JDK8以及以前版本:



而Java9的結構目錄:


對目錄做相應的介紹:

Java 9 的定義功能是一套全新的模塊系統。當代碼庫越來越大,創建復雜,盤根錯節的**“意大利面條式代碼”的幾率呈指數級的增長**。這時候就得面對兩個基礎的問題: 很難真正地對代碼進行封裝, 而系統并沒有對不同部分(也就是 JAR 文件)之間的依賴關系有個明確的概念。每一個公共類都可以被類路徑之下任何其它的公共類所訪問到, 這樣就會導致無意中使用了并不想被公開訪問的 API。此外,類路徑本身也存在問題: 你怎么知曉所有需要的 JAR 都已經有了, 或者是不是會有重復的項呢? 模塊系統把這倆個問題都給解決了

在模塊的 src 下創建 module-info.java 文件,來描述依賴和導出(暴露)。

requires:指明對其它模塊的依賴。
exports:控制著哪些包可以被其它模塊訪問到。所有不被導出的包
默認都被封裝在模塊里面。

2、Java 的 REPL 工具: jShell 命令

REPL:read - evaluate - print - loop
這個簡單的說就是能想腳本語言那樣,所見即所得。之前我們用java,哪怕只想輸出一句hello world,都是非常麻煩的。需要建文件、寫代碼、編譯、運行等等。現在有了jShell工具,實在太方便了

  • 即寫即得、快速運行


這樣我就進入了jshell環境。下面Hello World就是這么簡單了

  • jShell 也可以從文件中加載語句或者將語句保存到文件中(使用Open命令)
  • jShell 也可以是 tab 鍵進行自動補全和自動添加分號

    列出當前 session 里所有有效的代碼片段:/list

3、多版本兼容 jar 包(這個在處理向下兼容方面,非常好用)

當一個新版本的 Java 出現的時候,你的庫用戶要花費數年時間才會
切換到這個新的版本。這就意味著庫得去向后兼容你想要支持的最老
的 Java 版本(許多情況下就是 Java 6 或者 Java7)。這實際上意味著
未來的很長一段時間,你都不能在庫中運用 Java 9 所提供的新特性。
幸運的是,多版本兼容 jar 功能能讓你創建僅在特定版本的 Java 環境
中運行庫程序選擇使用的 class 版本

案例:略

4、語法改進:接口的私有方法

在 Java 9 中,接口更加的靈活和強大,連方法的訪問權限修飾符
都可以聲明為 private 的了,此時方法將不會成為你對外暴露的 API
的一部分(個人認為,這肯定是JDK8遺漏了的一個點,哈哈)
看個例子:

 public static String staticFun() {        privateFun();        return "";    }    default String defaultFun() {        privateFun();        return "";    }    private static void privateFun() {        System.out.println("我是私有方法~");    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

這樣子是沒有問題,可以正常調用和使用的。但是需要注意一下兩點

  1. 私有方法可以是static,也可以不是。看你需要default方法調用還是static方法調用
  2. 私有方法只能用private修飾,不能用protected。若不寫,默認就是public,就是普通靜態方法了。
default String defaultFun() {        privateFun();        return "";    }    private void privateFun() {        System.out.println("我是私有方法~");    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4、語法改進:鉆石操作符(Diamond Operator)使用升級 泛型

在 java 8 中如下的操作是會報錯的:

 public static void main(String[] args) {        Set<String> set1 = new HashSet<>(); //最常用的初始化        //Set<String> set2 = new HashSet<>(){}; //在JDK8中報錯        Set<String> set2 = new HashSet<String>(){}; //這樣在JDK8中也正常        Set<String> set3 = new HashSet<String>(){{}}; //這樣也都是正常的    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

由此課件,報錯的那種情況是因為在JDK8中,還不能直接推斷出鉆石操作符里面的類型而報錯。而我們在JDK9以后,就可以直接這么寫了:

public static void main(String[] args) {        Set<String> set1 = new HashSet<>(); //最常用的初始化        Set<String> set2 = new HashSet<>(){}; //在JDK8中報錯        Set<String> set3 = new HashSet<>(){{}}; //這樣也都是正常的    }
  • 1
  • 2
  • 3
  • 4
  • 5

這樣寫都是不會報錯,可以直接書寫使用的。相當于直接創建了一個HashMap的子類。

5、語法改進:UnderScore(下劃線)使用的限制

這個點非常的小。距離說明就懂了
在Java8中,我們給變量取名直接就是_

public static void main(String[] args) {       String _ = "hello";       System.out.println(_); //hello    }
  • 1
  • 2
  • 3
  • 4


我們很清晰的看到,Java8其實給出了提示,但是編譯運行都是能通過的,而到了Java9:

直接就提示_是關鍵字,編譯都過不了了。

6、底層結構:String 存儲結構變更(這個很重要)

UTF-8表示一個字符是個動態的過程,可以能用1、2、3個字節都是有可能的。但是UTF-16明確的就是不管你是拉丁文、中文等,都是恒定的用兩個字節表示

JDK8的字符串存儲在char類型的數組里面,不難想象在絕大多數情況下,char類型只需要一個字節就能表示出來了,比如各種字母什么的,兩個字節存儲勢必會浪費空間,JDK9的一個優化就在這,內存的優化。
Java8:

private final char value[];

Java9:

private final byte[] value;

結論:String 再也不用 char[] 來存儲啦,改成了 byte[] 加上編碼標
記,節約了不少空間。由于底層用了字節數組byte[]來存儲,所以遇上非拉丁文,JDK9配合了一個encodingFlag來配合編碼解碼的

so,相應的StringBuffer 和 StringBuilder 也對應的做出了對應的變化。

有的人擔心,這會不會影響到我的charAt方法呢?那我們來看看:

public static void main(String[] args) {        String str = "hello";        String china = "方世享";        System.out.println(str.charAt(1)); //e        System.out.println(china.charAt(1)); //世    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

顯然,這個對上層的調用者是完全透明的,完全是底層的數據結構存儲而已。但是有必要對比一下源碼,還是有非常大的區別的:
java8的charAt方法源碼: 實現起來簡單很多吧

 public char charAt(int index) {        if ((index < 0) || (index >= value.length)) {            throw new StringIndexOutOfBoundsException(index);        }        return value[index];    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

java9的charAt方法源碼:

public char charAt(int index) {        if (isLatin1()) {            return StringLatin1.charAt(value, index);        } else {            return StringUTF16.charAt(value, index);        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

7、集合工廠方法:快速創建只讀集合

為了保證數據的安全性,有時候我們需要創建一個只讀的List。在JDK8的時候,我們只能這么做:

Collections.unmodifiableList(list)Collections.unmodifiableSet(set)Collections.unmodifiableMap(map)
  • 1
  • 2
  • 3

Tips:Arrays.asList(1,2,3)創建的List也是只讀的,不能添加刪除,但是一般我們并不會把他當作只讀來用。

可以說是比較繁瑣的一件事。Java 9 因此引入了方便的方法,這使得類似的事情更容易表達。調用集合中靜態方法 of(),可以將不同數量的參數傳輸到此工廠方法。此功能可用于 Set 和 List,也可用于 Map 的類似形式。此時得到
的集合,是不可變的:

List<String> list = List.of("a", "b", "c");        Set<String> set = Set.of("a", "b", "c");        //Map的兩種初始化方式,個人喜歡第二種,語意更加清晰些,也不容易錯        Map<String, Integer> map1 = Map.of("Tom", 12, "Jerry", 21,                "Lilei", 33, "HanMeimei", 18);        Map<String, Integer> map2 = Map.ofEntries(                Map.entry("Tom", 89),                Map.entry("Jim", 78),                Map.entry("Tim", 98)        );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

處于好奇心,可以讓大家再對比一下類型,看看怎么實現的:

public static void main(String[] args) {        List<String> list = List.of("a", "b", "c");        List<String> listOld = Collections.unmodifiableList(Arrays.asList("a", "b", "c"));        System.out.println(list.getClass().getName()); //java.util.ImmutableCollections$ListN        System.out.println(listOld.getClass().getName()); //java.util.Collections$UnmodifiableRandomAccessList    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

8、增強的 Stream API

在 Java 9 中,Stream API 變得更好,Stream 接口中添加了 4 個新的方法:dropWhile, takeWhile, ofNullable,還有個 iterate 方法的新重載方法,可以讓你提供一個 Predicate (判斷條件)來指定什么時候結束迭代。

除了對 Stream 本身的擴展,Optional 和 Stream 之間的結合也
得到了改進。現在可以通過 Optional 的新方法 stream() 將一個
Optional 對象轉換為一個(可能是空的) Stream 對象

  • takeWhile():返回從開頭開始的盡量多的元素
  • dropWhile() :行為與 takeWhile 相反,返回剩余的元素
  • ofNullable():Stream 不能全為 null,否則會報空指針異常。而 Java 9 中的ofNullable健壯性就比of強很多。可以包含一個非空元素,也可以創建一個空 Stream
//報 NullPointerException   因為Of方法不允許全為null的//Stream<Object> stream1 = Stream.of(null);//System.out.println(stream1.count());//ofNullable():允許值為 nullStream<Object> stream1 = Stream.ofNullable(null);System.out.println(stream1.count());//0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • iterator()重載方法。如下,相當于不僅僅是limit,而是可以寫邏輯來判斷終止與否了

9、全新的 HTTP 客戶端 API

HTTP,用于傳輸網頁的協議,早在 1997 年就被采用在目前的 1.1
版本中。直到 2015 年,HTTP2 才成為標準。

Java 9 中有新的方式來處理 HTTP 調用。它提供了一個新的 HTTP客戶端( HttpClient ), 它 將 替代僅適用于 blocking 模式的HttpURLConnection (HttpURLConnection是在HTTP 1.0的時代創建的,并使用了協議無關的方法),并提供對 WebSocket 和 HTTP/2 的支持。

此外,HTTP 客戶端還提供 API 來處理 HTTP/2 的特性,比如流和
服務器推送等功能。全新的 HTTP 客戶端 API 可以從 jdk.incubator.httpclient 模塊中獲取。因為在默認情況下,這個模塊是不能根據 classpath 獲取的,需要使用 add modules 命令選項配置這個模塊,將這個模塊添加到 classpath中。
栗子:

HttpClient client = HttpClient.newHttpClient();HttpRequest req = HttpRequest.newBuilder(URI.create("http://www.baidu.com")).GET().build();HttpResponse<String> response = client.send(req, HttpResponse.BodyHandler.asString());System.out.println(response.statusCode());System.out.println(response.version().name());System.out.println(response.body());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

10、其它特性

Deprecated 廢棄了相關 API

Java 9 廢棄或者移除了幾個不常用的功能。其中最主要的是
Applet API,現在是標記為廢棄的。隨著對安全要求的提高,主流瀏
覽器已經取消對 Java 瀏覽器插件的支持

智能 Java 編譯工具

智能 java 編譯工具( sjavac )的第一個階段始于 JEP139 這個項目,用于在多核處理器情況下提升 JDK 的編譯速度

JDK 9 還更新了 javac 編譯器以便能夠將 java 9 代碼編譯運行在低版本 Java 中

統一的 JVM 日志系統
javadoc 的 HTML 5 支持

Nashorn 項目在 JDK 9 中得到改進,它為 Java 提供輕量級的Javascript 運行時。
JDK 9 包含一個用來解析 Nashorn 的 ECMAScript 語法樹的API。這個 API 使得 IDE 和服務端框架不需要依賴 Nashorn 項目的內部實現類,就能夠分析 ECMAScript 代碼。

Javascript 引擎升級:Nashorn(該引擎在8中首次引入,非常好用)
java 的動態編譯器

**JIT(Just-in-time)**編譯器可以在運行時將熱點編譯成本地代碼,
速度很快。但是 Java 項目現在變得很大很復雜,因此 JIT 編譯器需
要花費較長時間才能熱身完,而且有些 Java 方法還沒法編譯,性能
方面也會下降。AoT 編譯就是為了解決這些問題而生的

JIT是個很大的研究課題,阿里有專門的團隊搞這一塊

最后:

Java9有一個重大的變化,就是垃回收器默認采用了G1。

Java 9 移除了在 Java 8 中 被廢棄的垃圾回收器配置組合,同時把G1設為默認的垃圾回收器實現。替代了之前默認使用的Parallel GC,對于這個改變,evens的評論是醬紫的:這項變更是很重要的,因為相對于Parallel來說,G1會在應用線程上做更多的事情,而Parallel幾乎沒有在應用線程上做任何事情,它基本上完全依賴GC線程完成所有的內存管理。這意味著切換到G1將會為應用線程帶來額外的工作,從而直接影響到應用的性能

CMS收集器與G1收集器的區別,參考:CMS收集器與G1收集器

本站僅提供存儲服務,所有內容均由用戶發布,如發現有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Java程序員必備基礎:JDK 5-15都有哪些經典新特性
Java9、10、11、12、13、14、15、16、17個版本新特性
JDK各個版本的新特性jdk1.5-jdk1.8
java的jdk已經更新到15了,為什么你還在用java8?
JDK5的新特性:增強for
Java 8 新特性
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服

主站蜘蛛池模板: 芒康县| 新邵县| 延寿县| 嘉鱼县| 盖州市| 普定县| 潮州市| 江城| 贵港市| 磐石市| 保山市| 杨浦区| 甘洛县| 宁晋县| 孟州市| 赤城县| 鹰潭市| 琼结县| 阳城县| 柘荣县| 冷水江市| 广西| 仁寿县| 宁强县| 屯留县| 太原市| 广宁县| 越西县| 宝兴县| 犍为县| 礼泉县| 平塘县| 德钦县| 格尔木市| 萍乡市| 江永县| 南充市| 监利县| 晋江市| 林西县| 伊宁市|