Java9新特性

Java9新特性主要發生的改變:

    1,  模塊化系統

    2,  Java 的REPL工具: jShell

    3,  接口中聲明私有方法

    4,  鑽石操作符升級

    5,  try結構的語法升級

    6,  String底層存儲結構的變更

    7,  集合工廠方法創建只讀集合

    8,  InputStream中transferTo()方法

    9,  StreamAPI新增的4個方法

    10,Optional的新方法stream()

    11,升級的Nashorn引擎

模塊化系統

1,模塊將由通常的類和新的模塊聲明文件(module-info.java)組成。該文件是位於java代碼結構的頂層,該模塊描述符明確地定義了我們的模塊需要什麼依賴關係,以及哪些模塊被外部使用。在exports子句中未提及的所有包默認情況下將封裝在模塊中,不能在外部使用。例子如下:
在這裏插入圖片描述在這裏插入圖片描述
2,要是module-info.java不能創建,請檢查jdk的版本,要求jdk9以上的版本
在這裏插入圖片描述
3,要想在Test01模塊中調用Test02模塊下包中的結構,需要在Test02的module-info.java中聲明:

module Test02 {
    //exports :控制着哪些包可以被其它模塊訪問到 。 所有不被導出的包默認都被封裝在模塊裏面
    exports bean;
}

4,對應在Test01 模塊的src下創建module-info.java文件:

module Test01 {
    //requires :指明對其它模塊的依賴。
    requires Test02;
}

Java 的REPL工具: jShell

像Python 和 Scala 之類的語言早就有交互式編程環境 REPL (read - evaluate - print -loop)了,以交互式的方式對語句和表達式進行求值。開發者只需要輸入一些代碼,就可以在編譯前獲得對程序的反饋。而之前的Java版本要想執行代碼,必須創建文件、聲明類、提供測試方法方可實現。

1,調出 jShell
jshell
在這裏插入圖片描述
2,獲取幫助
在這裏插入圖片描述
3,沒有受檢異常 ( 編譯時異常)
在這裏插入圖片描述
4,使用外部代碼編輯器來編寫Java
在這裏插入圖片描述5,退出
在這裏插入圖片描述

接口中聲明私有方法

jdk9中允許接口中定義私有的方法
接口中的靜態方法只能由接口自己調用,接口的實現類不能調用接口的靜態方法,使用如下:

interface MyInterface {
    void normalInterfaceMethod();

    default void methodDefault1() {
        init();
    }

    public default void methodDefault2() {
        init();
    }

    // This method is not part of the public API exposed by MyInterface
    private void init() {
        System.out.println("默認方法中的通用操作");
    }
}
class MyInterfaceImpl implements MyInterface {
    @Override
    public void normalInterfaceMethod() {
        System.out.println("實現接口的方法");
    }
}

public class MyInterfaceTest {
    public static void main(String[] args) {
        MyInterfaceImpl impl = new MyInterfaceImpl();
        impl.methodDefault1();
        // impl.init();//不能調用
    }
}

鑽石操作符使用升級

1,鑽石操作符與匿名內部類在java8中不能共存,在Java9可以

2,我們將能夠與匿名實現類共同使用鑽石操作符(diamond operator)在Java 8
中如下的操作是會報錯的,如下:

//編譯報錯信息:Cannot use “<>” with anonymous inner classes.在java9中則可以編譯通過
Comparator<Object> com = new Comparator<>(){
	@Override
	public int compare(Object o1, Object o2) {
	return 0;
	}
};

try結構的語法升級

1,Java 8 中,可以實現資源的自動關閉,但是要求執行後必須關閉的所有資源必須在try子句中初始化,否則編譯不通過。如下例所示:

try(InputStreamReader reader = new InputStreamReader(System.in)){
	//讀取數據細節省略
}catch (IOException e){
	e.printStackTrace();
}

2,Java 9 中,用資源語句編寫try將更容易,我們可以在try子句中使用已經初始化過的資源,此時的資源是final的:

InputStreamReader reader = new InputStreamReader(System.in);
OutputStreamWriter writer = new OutputStreamWriter(System.out);
try(reader;writer){
    //reader是final的,不可再被賦值
    //reader = null;
    char[] chars = new char[20];
    int len;
    if((len = reader.read(chars)) != -1){
        String str = new String(chars,0,len);
        writer.write(str,0,len);
    }
}catch (IOException e){
    e.printStackTrace();
}

String底層存儲結構的變更

String 再也不用 char[] 來存儲啦,改成了 byte[] 加上編碼標記,節約了一些空間,StringBuffer和StringBuilder也隨着改變。

集合工廠方法創建只讀集合

1,jdk8要創建一個只讀、不可改變的集合,必須構造和分配它,然後添加元素,最後包裝成一個不可修改的集合。

List<String> namesList = new ArrayList <>();
namesList.add("Tommey");
namesList.add("Bob");
namesList.add("CC");
namesList = Collections.unmodifiableList(namesList);
System.out.println(namesList);

2,jdk9調用集合中靜態方法of(),可以將不同數量的參數傳輸到此工廠方法中。此功能可用於Set和List,也可用於Map的類似形式。此時得到的集合,是不可變的:在創建後,繼續添加元素到這些集合會導致 “UnsupportedOperationException”

List<String> list = List.of("a", "b", "c");
Set<String> set = Set.of("a", "b", "c");
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));

InputStream中transferTo()方法

InputStream 終於有了一個非常有用的方法:transferTo,可以用來將數據直接
傳輸到 OutputStream,使用如下:

ClassLoader cl = this.getClass().getClassLoader();
try (InputStream is = cl.getResourceAsStream("hello.txt");
     OutputStream os = new FileOutputStream("src\\hello1.txt")) {
    is.transferTo(os); // 把輸入流中的所有數據直接自動地複製到輸出流中
} catch (IOException e) {
    e.printStackTrace();
}

StreamAPI新增的4個方法

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

1,takeWhile() 的使用:

     用於從 Stream 中獲取一部分數據,接收一個 Predicate 來進行選擇。在有序的Stream 中takeWhile 返回從開頭開始的儘量多的元素。

    List<Integer> list = Arrays.asList(45, 43, 76, 87, 42, 77, 90, 73, 67, 88);
    list.stream().takeWhile(x -> x < 50).forEach(System.out::println);//45,43

2,dropWhile()的使用:

     dropWhile 的行爲與 takeWhile 相反,返回剩餘的元素。

list.stream().dropWhile(x -> x < 50).forEach(System.out::println);//76 ,87 ,42 ,77 ,90 ,73 ,67 ,88

3,ofNullable()的使用:

     Java 8 中 Stream 不能完全爲null,否則會報空指針異常。而 Java 9 中的 ofNullable 方法允許我們創建一個單元素 Stream,可以包含一個非空元素,也可以創建一個空Stream。

        // 報NullPointerException
        // Stream<Object> stream1 = Stream.of(null);
        // System.out.println(stream1.count());
        Stream<String> stringStream = Stream.of("AA", "BB", null);
        System.out.println(stringStream.count());// 3
        // ofNullable():允許值爲null
        Stream<Object> stream1 = Stream.ofNullable(null);
        System.out.println(stream1.count());// 0
        Stream<String> stream = Stream.ofNullable("hello world");
        System.out.println(stream.count());// 1

4,ofNullable()的使用:

     這個 iterate 方法的新重載方法,可以讓你提供一個 Predicate (判斷條件)來指定什麼時候結束迭代。

        // 原來的控制終止方式:
        Stream.iterate(1, i -> i + 1).limit(10).forEach(System.out::println);
        // 現在的終止方式:
        Stream.iterate(1, i -> i < 100, i -> i + 1).forEach(System.out::println);

Optional的新方法stream()

Optional類中stream()的使用:

        List<String> list = new ArrayList<>();
        list.add("Tommey");
        list.add("Tom");
        Optional<List<String>> optional = Optional.ofNullable(list);
        Stream<List<String>> stream = optional.stream();
        stream.flatMap(x -> x.stream()).forEach(System.out::println);

升級的Nashorn引擎

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章