1. 程式人生 > 程式設計 >JDK13新特性,讓開發效率更快一步

JDK13新特性,讓開發效率更快一步

JDK13到今天已經發布快2個月了,之前有零零散散的試過一些新的特性,但卻沒有整體的整理一下。想到作為Java開發,連使用的JDK(Java Developerment Kit)有什麼特性都不清楚,實在是有些不應該,想要進階為更有價值的JAVA開發人員,一定要跟得上JDK的最新特性。

那再來看下,這份遲來的JDK新特性一覽

JDK13

所有的JDK特性都會在JEP進度中提出來和跟蹤:openjdk.java.net/jeps/0

對於每個JDK版本的有什麼特性在對應JDK主頁中檢視:openjdk.java.net/projects/jd…

JDK13主要有5個特性:

Dynamic CDS Archives

在JDK10中被引入的新特性,但是當時建立步驟比較繁瑣。

# JDK10中需要的步驟
1. 需要指定要歸檔那些類  -XX:DumpLoadedClassList=classes.lst
2. 建立歸檔   -Xshare:dump  -XX:SharedArchiveFile -XX:SharedClassListFile=classes.lst
3. 使用歸檔  -Xshare:on -XX:SharedArchiveFile
複製程式碼

在JDK13中引入新的選項,在程式退出時自動歸檔:

java -XX:ArchiveClassesAtExit=app.jsa -cp app.jar HelloDemo
複製程式碼

使用歸檔步驟與之前相同,預設-Xshare:on是開啟的

類載入過程:

載入->驗證->準備->解析->初始化->使用->解除安裝

  • 載入:找到Class的位置,從Class位置讀取Class檔案內容
  • 驗證:檔案格式的驗證、元資料的驗證、位元組碼驗證和符號引用驗證。
  • 準備:正式為類變數分配記憶體並設定類變數初始值的階段,這些記憶體都將在方法區中分配。儲存為JDK內部資料結構
  • 解析:虛擬機器器將常量池中的符號引用轉化為直接引用的過程,解析介面,欄位解析
  • 初始化:建立類

CDS的設計目的主要為了提升啟動應用時的速度,class-data只需要建立一次,後續重複使用,減少了載入,驗證,準備階段。可能會有解析階段

參考:App CDS實戰

ZGC: Uncommit Unused Memory

ZGC從JDK11中被引入進來,在進行GC的時候保證更短的停頓時間,10ms以下,在JDK13中新增了歸還未提交,未使用的記憶體給作業系統

ZGC由許多的ZPage組成,Zpage是不同大小的記憶體區域,分為小、中、大。當ZGC壓縮記憶體時,Zpage被清空到ZPageCache中,ZpageCache是準備隨時被用到的區域,如果被使用,會立刻從ZpageCache中移除到Zpage中,但是如果ZpageCache中的Zpage長時間未使用,則變為未提交使用的記憶體,後續可還給作業系統。

When ZGC compacts the heap,ZPages are freed up and inserted into a page cache,the ZPageCache.

#設定一個時間多久從ZpageCache中移除(evict)Zpage
-XX:+UnlockExperimentalVMOptions -XX:+ZUncommit  -XX:ZUncommitDelay=<seconds> 
複製程式碼

參考:ZGC完全指南

Reimplement the Legacy Socket API

JDK底層對Socket的實現非常的古老,從JDK1.0中被使用一直到現在,底層為很早的Java和C程式碼,對於開發JDK的人來說,非常的難以維護和Debug,因此重新實現了Socket API的介面。

  • JDK13之前,使用PlainSocketImpl

  • JDK13引入了,NioSocketImpl替換PlainSocketImpl。

來一個HelloWorld案例:

public class HelloApp {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8888)) {

            boolean running = true;
            System.out.println("listened 8888");
            while (running) {
                Socket clientSocket = serverSocket.accept();

                //do something with clientSocket
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
複製程式碼

但是我們仍然可以切換為PlainSocketImpl。需配置jdk.net.usePlainSocketImpl

/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -XX:+TraceClassLoading  me/aihe/HelloApp.java | grep -i socketI
複製程式碼

image-20191108074323662

/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/bin/java -XX:+TraceClassLoading -Djdk.net.usePlainSocketImpl  me/aihe/HelloApp.java | grep -i socketI
複製程式碼

image-20191108074413822

Switch Expressions (Preview)

引入了一個新的關鍵字yield用於返回switch語句的內容。最開始我們寫switch語句都要在語句之前做一些初始化變數,現在可以直接得到swicth語句額返回結果

最開始的switch寫法:

int numLetters;
switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        numLetters = 6;
        break;
    case TUESDAY:
        numLetters = 7;
        break;
    case THURSDAY:
    case SATURDAY:
        numLetters = 8;
        break;
    case WEDNESDAY:
        numLetters = 9;
        break;
    default:
        throw new IllegalStateException("Wat: " + day);
}
複製程式碼

在JDK13中可以這樣寫:

# 沒有邏輯的返回
int numLetters = switch (day) {
    case MONDAY,FRIDAY,SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY,SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};

# 邏輯較多的處理
      String result = switch (number) {
            case 1,2:
            		// 邏輯程式碼
                yield "one or two";
            case 3:
            	  // 邏輯程式碼
                yield "three";
            case 4,5,6:
                yield "four or five or six";
            default:
                yield "unknown";
        };
        return result;
複製程式碼

Text Blocks (Preview)

最開始寫長字串的時候,往往要使用多個字串拼接,一是浪費效能,而是看起來很難看。尤其寫HTML字串或者SQL語句時。

// 比如HTML
String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello,world</p>\n" +
              "    </body>\n" +
              "</html>\n";
複製程式碼

現在可以寫成:

String html = """
              <html>
                  <body>
                      <p>Hello,world</p>
                  </body>
              </html>
              """;
複製程式碼

注意:

  • 其中有個細微的區別,是開頭"""之後必須另起一行,另外結尾的"""是否另起一行有不同的效果
  • 注意在使用的時候每一行可能需要處理兩邊的空格
"""
line 1
line 2
line 3
"""

=>

"line 1\nline 2\nline 3\n"
複製程式碼
"""
line 1
line 2
line 3"""

=>

"line 1\nline 2\nline 3"
複製程式碼

最後

JDK13在一定程度上還是可以加快我們的開發速度...,最重要的是其歸檔特性可以大大減少我們應用的啟動時間,ZGC則讓我們在記憶體吃緊時,又帶來了福音。

值得一試!