Java13的新特性
Java語言特性系列
- Java5的新特性
- Java6的新特性
- Java7的新特性
- Java8的新特性
- Java9的新特性
- Java10的新特性
- Java11的新特性
- Java12的新特性
- Java13的新特性
- Java14的新特性
序
本文主要講述一下Java13的新特性
版本號
java -version
openjdk version "13" 2019-09-17
OpenJDK Runtime Environment (build 13+33)
OpenJDK 64-Bit Server VM (build 13+33,mixed mode,sharing)
複製程式碼
從version資訊可以看出是build 13+33
特性列表
350: Dynamic CDS Archives
JDK5引入了Class-Data Sharing可以用於多個JVM共享class,提升啟動速度,最早只支援system classes及serial GC JDK9對其進行擴充套件以支援application classes及其他GC演演算法 java10的新特性JEP 310: Application Class-Data Sharing擴充套件了JDK5引入的Class-Data Sharing,支援application的Class-Data Sharing並開源出來(以前是commercial feature) JDK11將-Xshare:off改為預設-Xshare:auto,以更加方便使用CDS特性 JDK12的
341: Default CDS Archives即在64-bit平臺上編譯jdk的時候就預設在${JAVA_HOME}/lib/server目錄下生成一份名為classes.jsa的預設archive檔案(大概有18M)方便大家使用 JDK13的這個特性支援在Java application執行之後進行動態archive
- 匯出jsa
java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello
複製程式碼
- 使用jsa
java -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello
複製程式碼
351: ZGC: Uncommit Unused Memory
Java12的346: Promptly Return Unused Committed Memory from G1新增了兩個引數分別是G1PeriodicGCInterval及G1PeriodicGCSystemLoadThreshold用於GC之後重新調整Java heap size,然後將多餘的記憶體歸還給作業系統 Java12的189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)擁有引數-XX:ShenandoahUncommitDelay=來指定ZPage的page cache的失效時間,然後歸還記憶體 Java13則給ZGC新增歸還unused heap memory給作業系統的特性;它新增了幾個引數,-XX:ZUncommitDelay=用於指定ZPage的page cache的失效時間;ZGC的歸還記憶體預設是開啟的,可以使用-XX:-ZUncommit來顯式禁用
353: Reimplement the Legacy Socket API
本特性替換了java.net.Socket以及java.net.ServerSocket API的底層實現;它使用NioSocketImpl來替換JDK1.0的PlainSocketImpl;如果要繼續使用舊版的Socket實現,可以使用-Djdk.net.usePlainSocketImpl引數來切換到舊版本
/Library/Java/JavaVirtualMachines/jdk-13.jdk/Contents/Home/lib/src.zip!/java.base/java/net/SocketImpl.java
public abstract class SocketImpl implements SocketOptions {
private static final boolean USE_PLAINSOCKETIMPL = usePlainSocketImpl();
private static boolean usePlainSocketImpl() {
PrivilegedAction<String> pa = () -> NetProperties.get("jdk.net.usePlainSocketImpl");
String s = AccessController.doPrivileged(pa);
return (s != null) && !s.equalsIgnoreCase("false");
}
/**
* Creates an instance of platform's SocketImpl
*/
@SuppressWarnings("unchecked")
static <S extends SocketImpl & PlatformSocketImpl> S createPlatformSocketImpl(boolean server) {
if (USE_PLAINSOCKETIMPL) {
return (S) new PlainSocketImpl(server);
} else {
return (S) new NioSocketImpl(server);
}
}
//......
}
複製程式碼
SocketImpl的USE_PLAINSOCKETIMPL取決於usePlainSocketImpl方法,而它會從NetProperties讀取dk.net.usePlainSocketImpl配置,如果不為null且不為false,則usePlainSocketImpl方法返回true;createPlatformSocketImpl會根據USE_PLAINSOCKETIMPL來建立PlainSocketImpl或者NioSocketImpl
354: Switch Expressions (Preview)
本特性主要是使用yield替換了break來避免歧義,因為break可以用來進行跳轉執行類似goto的操作
@Test
public void testSwitchYield(){
String dayOfWeek = switch(1){
case 1 -> {
String day = "Monday";
yield day;
}
case 2 -> {
String day = "Tuesday";
yield day;
}
default -> "Unknown";
};
System.out.println(dayOfWeek);
}
複製程式碼
355: Text Blocks (Preview)
本特性主要引入了Text Blocks,使用"""來包圍一段text block,可以內建佔位符最後使用String.format來填充
@Test
public void testTextBlock(){
// Without Text Blocks
String html = "<html>\n" +
" <body>\n" +
" <p>Hello,Escapes</p>\n" +
" </body>\n" +
"</html>\n";
System.out.println(html);
// With Text Blocks
String html2 = """
<html>
<body>
<p>Hello,%s</p>
</body>
</html>""";
System.out.println(String.format(html2,"World"));
String htmlWithNewLine = """
<html>
<body>
<p>Hello World</p>
</body>
</html>
""";
System.out.print(htmlWithNewLine);
System.out.println("a new line");
}
複製程式碼
需要注意text blocks不能在一行,另外如果結尾的"""在新的一行則會輸出新的一行
細項解讀
上面列出的是大方面的特性,除此之外還有一些api的更新及廢棄,主要見JDK 13 Release Notes,這裡舉幾個例子。
新增項
- 新增FileSystems.newFileSystem(Path,Map<String,?>) Method
- 新的java.nio.ByteBuffer Bulk get/put Methods Transfer Bytes Without Regard to Buffer Position
- 支援Unicode 12.1
- 新增-XX:SoftMaxHeapSize Flag,目前僅僅對ZGC起作用
- ZGC的最大heap大小增大到16TB
移除項
- 移除awt.toolkit System Property
- 移除Runtime Trace Methods
- 移除-XX:+AggressiveOpts
- 移除Two Comodo Root CA Certificates、Two DocuSign Root CA Certificates
- 移除內部的com.sun.net.ssl包
廢棄項
- 廢棄-Xverify:none及-noverify
- 廢棄rmic Tool並準備移除
- 廢棄javax.security.cert並準備移除
已知問題
- 不再支援Windows 2019 Core Server
- 使用ZIP File System (zipfs) Provider來更新包含Uncompressed Entries的ZIP或JAR可能造成檔案損壞
其他事項
- GraphicsEnvironment.getCenterPoint()及getMaximumWindowBounds()已跨平臺統一
- 增強了JAR Manifest的Class-Path屬性處理
jdk.net.URLClassPath.showIgnoredClassPathEntries屬性設定為true可以用來幫助檢視非法的Class-Path entries
- 針對Negatively Sized Argument,StringBuffer(CharSequence)及StringBuilder(CharSequence)會丟擲NegativeArraySizeException
- linux的預設程式啟動機制已經使用posix_spawn
- Lookup.unreflectSetter(Field)針對static final fields會丟擲IllegalAccessException
- 使用了java.net.Socket.setSocketImplFactory及java.net.ServerSocket.setSocketFactory方法的要注意,要求客戶端及服務端要一致,不能一端使用自定義的factory一端使用預設的factory
- SocketImpl的supportedOptions,getOption及setOption方法的預設實現發生了變化,預設的supportedOptions返回空,而預設的getOption,及setOption方法丟擲UnsupportedOperationException
- JNI NewDirectByteBuffer建立的Direct Buffer為java.nio.ByteOrder.BIG_ENDIAN
- Base64.Encoder及Base64.Decoder可能丟擲OutOfMemoryError
- 改進了Serial GC Young pause time report
- 改進了MaxRAM及UseCompressedOops引數的行為
小結
- Java13主要新增瞭如下特性
- 350: Dynamic CDS Archives
- 351: ZGC: Uncommit Unused Memory
- 353: Reimplement the Legacy Socket API
- 354: Switch Expressions (Preview)
- 355: Text Blocks (Preview)
- 語法層面,改進了Switch Expressions,新增了Text Blocks,二者皆處於Preview狀態;API層面主要使用NioSocketImpl來替換JDK1.0的PlainSocketImpl
- GC層面則改進了ZGC,以支援Uncommit Unused Memory