Java 14 的五大特性

前言

下載

http://jdk.java.net/14/
在這裏插入圖片描述

使用

請下載最新版本的 idea。使用 2020版本。、
設置語言級別。
在這裏插入圖片描述

1、文本塊

使用 3 個 雙引號(“““)以及反斜線(\) 和 反斜線加s(\s)來表示一個字符創。

符號 含義
““” 表述一個字符串,多行默認會換行
\ 表示不插入換行符
\s 表示插入空格

舉例

/**
  * 文本塊:可以將之前使用加拼接的字符串代替掉<br>
  * <code>
  *     String lines = "你好,我叫做" +
  *        "小馮,很高興" +
  *        "認識你!";
  * </code>
  *  <br>
  * 其中,<code>\</code> 是表示不插入換行符號;<code>\s</code> 表示空格
  */
 private static void textBlocks() {
     String lines = """
         你好,我叫做\
         小馮,很高興\
         認識你!
         你好壞~\
         """;

     /*
      * 打印結果:
      * 你好,我叫做小馮,很高興認識你!
      * 你好壞~
      */
     System.out.println(lines);
 }

解析

查看編譯後的代碼是:

private static void textBlocks() {
    String lines = "你好,我叫做小馮,很高興認識你!\n你好壞~";
    System.out.println(lines);
}

2、switch 表達式

switch 中,可以增加返回值。使用單箭頭指向結果。
比如,以下代碼,輸入了 year 之後,會打印出:這是年。

舉例

/**
 * switch 表達式的使用
 */
private static void switchExpression() {
    System.out.println("請輸入:year,day,month");
    // 鍵盤輸入
    var envent = new Scanner(System.in).next();
    // 可以返回結果的 switch
    var switchEnvent = switch (envent) {
        case "day" -> "這是天";
        case "year" -> "這是年";
        case "month" -> "這是月";
        case "exit","bye","goodbye" -> "退出";
        default ->  "It is a " + envent;
    };

    System.out.println(switchEnvent);
}

解析

查看編譯後的代碼:

private static void switchExpression() {
    System.out.println("請輸入:year,day,month");
    String envent = (new Scanner(System.in)).next();
    byte var3 = -1;
    switch(envent.hashCode()) {
    case 98030:
        if (envent.equals("bye")) {
            var3 = 4;
        }
        break;
    case 99228:
        if (envent.equals("day")) {
            var3 = 0;
        }
        break;
    case 3127582:
        if (envent.equals("exit")) {
            var3 = 3;
        }
        break;
    case 3704893:
        if (envent.equals("year")) {
            var3 = 1;
        }
        break;
    case 104080000:
        if (envent.equals("month")) {
            var3 = 2;
        }
        break;
    case 207022353:
        if (envent.equals("goodbye")) {
            var3 = 5;
        }
    }

    String var10000;
    switch(var3) {
    case 0:
        var10000 = "這是天";
        break;
    case 1:
        var10000 = "這是年";
        break;
    case 2:
        var10000 = "這是月";
        break;
    case 3:
    case 4:
    case 5:
        var10000 = "退出";
        break;
    default:
        var10000 = "It is a " + envent;
    }

    String switchEnvent = var10000;
    System.out.println(switchEnvent);
}

3、instanceof 自動轉換

在使用時,如果可以轉換(即instanceof 返回爲true),指定一個變量當做轉換後的變量即可。

舉例

/**
 * instanceof 的使用
 * @param object 任意對象
 */
private static void instanceOf(Object object){
    // 如果是 Integer 類型
    // 會強制類型轉換爲目標類型
    if(object instanceof Integer num){
        System.out.println("這是一個整數:" + num);
    } else if(object instanceof String string){
        System.out.println("這是一個字符串:" + string);
    }
}

解析

查看其編譯後的代碼可以看出:

private static void instanceOf(Object object) {
    Integer num;
    if (object instanceof Integer && (num = (Integer)object) == (Integer)object) {
        System.out.println("這是一個整數:" + num);
    } else {
        String string;
        if (object instanceof String && (string = (String)object) == (String)object) {
            System.out.println("這是一個字符串:" + string);
        }
    }
}

4、Record 標誌

使用這個標註,可以創建不可改屬性的實體類。
稍微不同的是,它可以自動生成 equals ,hashcode等方法,另外它提供的 getter 方法並沒有 get 前綴。

舉例

/**
 * Preview 創建一個不可改的類,包含有equals、hashCode和toString方法的實現
 */
record People(String name, String password, Integer age){}

測試與解析

當使用上述定義的方法定義了類 People之後,它在編譯之後:

final class People extends java.lang.Record {
    private final java.lang.String name;
    private final java.lang.String password;
    private final java.lang.Integer age;

    public People(java.lang.String name, java.lang.String password, java.lang.Integer age) { /* compiled code */ }

    public java.lang.String toString() { /* compiled code */ }

    public final int hashCode() { /* compiled code */ }

    public final boolean equals(java.lang.Object o) { /* compiled code */ }

    public java.lang.String name() { /* compiled code */ }

    public java.lang.String password() { /* compiled code */ }

    public java.lang.Integer age() { /* compiled code */ }
}

當調用它時:

// Record 標誌,可以讓一個類擁有不可變的屬性,以及getter方法(沒有get前綴)
People people = new People("小馮", "123456", 24);
System.out.println(people.toString());
System.out.println(people.name());
System.out.println(people.password());
System.out.println(people.age());

5、NPE 的一個改動

這個改動,需要在 VM 參數中加上:

-XX:+ShowCodeDetailsInExceptionMessages

測試代碼承接第 4 條:

測試

/*
* 關於 npe 的優化
* 需要增加參數  -XX:+ShowCodeDetailsInExceptionMessages
* 以下程序會拋出空指針
* Exception in thread "main" java.lang.NullPointerException: Cannot invoke "People.name()" because "people" is null
* 	at HelloJava.main(HelloJava.java:29)
*/
people = null;
System.out.println(people.name().charAt(0));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章