Java语言特性系列
本文主要讲述一下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
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
java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello
java -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello
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=<milliseconds>来指定ZPage的page cache的失效时间,然后归还内存
Java13则给ZGC新增归还unused heap memory给操作系统的特性;它新增了几个参数,-XX:ZUncommitDelay=<seconds>用于指定ZPage的page cache的失效时间;ZGC的归还内存默认是开启的,可以使用-XX:-ZUncommit来显式禁用
本特性替换了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
本特性主要是使用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); }
本特性主要引入了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 ,这里举几个例子。
jdk.net.URLClassPath.showIgnoredClassPathEntries属性设置为true可以用来帮助查看非法的Class-Path entries
Java13主要新增了如下特性