Java 13 It has been officially released on September 17, 2019, Download Java 13 here Or here openJDK archived .
Java 13 features.
- JEP 350: dynamic CDS Archive
- JEP 351: ZGC: uncommit unused memory
- JEP 353: re implement the old socket API
- JEP 354: switch expression (Preview) (developer functions)
- JEP 355: text block (Preview) (developer functions)
JEP 350 dynamic CDS Archive
Java 10 introduces JEP 310 Application Class-Data Sharing . The JEP simplifies the process of creating CDS archives.
This command creates a CDS archive of. jar.
$ java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello
This command runs. jar using an existing CDS archive.
$ bin/java -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello
Class data sharing (CDS) improves startup performance by creating one class data archive at a time and reusing it so that the JVM does not have to create it again.
Please read the following articles to learn more about CDS:
JEP 351 ZGC: uncommission unused memory
Java 11 introduced JEP 333: Z garbage collector (experimental) ; provides a short pause time when cleaning up heap memory. However, even if it is not used for a long time, it will not return unused heap memory to the operating system.
The JEP enhances ZGC by returning unused heap memory to the operating system.
JEP-353 re implements the old socket API
java.net.Socket and java.net.ServerSocket The basic implementation of JDK 1.0 can be traced back to JDK 1.0, which is a combination of legacy Java and C code that is difficult to maintain and debug. This JEP introduces a new basic implementation for the Socket API, which is the default implementation in Java 13.
Before Java 13, it used PlainSocketImpl for SocketImpl
public class ServerSocket implements java.io.Closeable { /** * The implementation of this Socket. */ private SocketImpl impl; }
Java 13 introduces a new NioSocketImpl class to replace PlainSocketImpl. However, if there is a problem, we can still set the jdk.net.usePlainSocketImpl System properties to switch back to the old implementation PlainSocketImpl.
See a simple Socket example.
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class JEP353 { public static void main(String[] args) { try (ServerSocket serverSocket = new ServerSocket(8888)){ boolean running = true; while(running){ Socket clientSocket = serverSocket.accept(); //do something with clientSocket } } catch (IOException e) { e.printStackTrace(); } } }
In Java 13, the default implementation is NioSocketImpl
D:\test>javac JEP353.java D:\test>java JEP353 D:\test>java -XX:+TraceClassLoading JEP353 | findStr Socket [0.040s][info ][class,load] java.net.ServerSocket source: jrt:/java.base [0.040s][info ][class,load] jdk.internal.access.JavaNetSocketAccess source: jrt:/java.base [0.040s][info ][class,load] java.net.ServerSocket$1 source: jrt:/java.base [0.040s][info ][class,load] java.net.SocketOptions source: jrt:/java.base [0.040s][info ][class,load] java.net.SocketImpl source: jrt:/java.base [0.044s][info ][class,load] java.net.SocketImpl$$Lambda$1/0x0000000800ba0840 source: java.net.SocketImpl [0.047s][info ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base [0.047s][info ][class,load] sun.nio.ch.NioSocketImpl source: jrt:/java.base [0.047s][info ][class,load] sun.nio.ch.SocketDispatcher source: jrt:/java.base [0.052s][info ][class,load] java.net.SocketAddress source: jrt:/java.base [0.052s][info ][class,load] java.net.InetSocketAddress source: jrt:/java.base [0.052s][info ][class,load] java.net.InetSocketAddress$InetSocketAddressHolder source: jrt:/java.base [0.053s][info ][class,load] sun.net.ext.ExtendedSocketOptions source: jrt:/java.base [0.053s][info ][class,load] jdk.net.ExtendedSocketOptions source: jrt:/jdk.net [0.053s][info ][class,load] java.net.SocketOption source: jrt:/java.base [0.053s][info ][class,load] jdk.net.ExtendedSocketOptions$ExtSocketOption source: jrt:/jdk.net [0.053s][info ][class,load] jdk.net.SocketFlow source: jrt:/jdk.net [0.053s][info ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions source: jrt:/jdk.net [0.053s][info ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions$1 source: jrt:/jdk.net [0.054s][info ][class,load] jdk.net.ExtendedSocketOptions$1 source: jrt:/jdk.net [0.054s][info ][class,load] sun.nio.ch.NioSocketImpl$FileDescriptorCloser source: jrt:/java.base [0.055s][info ][class,load] java.net.Socket source: jrt:/java.base
We can set Djdk.net.usePlainSocketImpl System properties to switch back to PlainSocketImpl.
D:\test>java -Djdk.net.usePlainSocketImpl -XX:+TraceClassLoading JEP353 | findStr Socket [0.041s][info ][class,load] java.net.ServerSocket source: jrt:/java.base [0.041s][info ][class,load] jdk.internal.access.JavaNetSocketAccess source: jrt:/java.base [0.041s][info ][class,load] java.net.ServerSocket$1 source: jrt:/java.base [0.041s][info ][class,load] java.net.SocketOptions source: jrt:/java.base [0.041s][info ][class,load] java.net.SocketImpl source: jrt:/java.base [0.045s][info ][class,load] java.net.SocketImpl$$Lambda$1/0x0000000800ba0840 source: java.net.SocketImpl [0.048s][info ][class,load] sun.net.PlatformSocketImpl source: jrt:/java.base [0.048s][info ][class,load] java.net.AbstractPlainSocketImpl source: jrt:/java.base [0.048s][info ][class,load] java.net.PlainSocketImpl source: jrt:/java.base [0.048s][info ][class,load] java.net.AbstractPlainSocketImpl$1 source: jrt:/java.base [0.050s][info ][class,load] sun.net.ext.ExtendedSocketOptions source: jrt:/java.base [0.050s][info ][class,load] jdk.net.ExtendedSocketOptions source: jrt:/jdk.net [0.050s][info ][class,load] java.net.SocketOption source: jrt:/java.base [0.051s][info ][class,load] jdk.net.ExtendedSocketOptions$ExtSocketOption source: jrt:/jdk.net [0.051s][info ][class,load] jdk.net.SocketFlow source: jrt:/jdk.net [0.051s][info ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions source: jrt:/jdk.net [0.051s][info ][class,load] jdk.net.ExtendedSocketOptions$PlatformSocketOptions$1 source: jrt:/jdk.net [0.051s][info ][class,load] jdk.net.ExtendedSocketOptions$1 source: jrt:/jdk.net [0.051s][info ][class,load] java.net.StandardSocketOptions source: jrt:/java.base [0.051s][info ][class,load] java.net.StandardSocketOptions$StdSocketOption source: jrt:/java.base [0.053s][info ][class,load] sun.net.ext.ExtendedSocketOptions$$Lambda$2/0x0000000800ba1040 source: sun.net.ext.ExtendedSocketOptions [0.056s][info ][class,load] java.net.SocketAddress source: jrt:/java.base [0.056s][info ][class,load] java.net.InetSocketAddress source: jrt:/java.base [0.058s][info ][class,load] java.net.InetSocketAddress$InetSocketAddressHolder source: jrt:/java.base [0.059s][info ][class,load] java.net.SocketCleanable source: jrt:/java.base
JEP-354 switch expression (Preview)
Java 12 introduces JEP 325 Switch expression . Instead of breaking value, the JEP uses the yield keyword to return a value from the switch expression.
PS this is the preview language function in Java 13
In the traditional switch statement, we can return the following values:
private static String getNumber(int number) { String result = ""; switch (number) { case 1: case 2: result = "one or two"; break; case 3: result = "three"; break; case 4: case 5: case 6: result = "four or five or six"; break; default: result = "unknown"; } ; return result; }
In Java 12, we can use break to return a value from switch.
private static String getNumberViaBreak(int number) { String result = switch (number) { case 1, 2: break "one or two"; case 3: break "three"; case 4, 5, 6: break "four or five or six"; default: break "unknown"; }; return result; }
In Java 13, the above Java 12 value break is discarded and the yield keyword is used to return the value.
private static String getNumberViaYield(int number) { return 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"; }; }
Or something like that
private static String getNumberViaYield2(int number) { return switch (number) { case 1, 2: yield "one or two"; case 3: yield "three"; case 4, 5, 6: int i = 0; i++; yield "four or five or six : " + i; default: yield "unknown"; }; }
Java 13 still supports rule tags or arrows or case L
private static String getNumberViaCaseL(int number) { return switch (number) { case 1, 2 -> "one or two"; case 3 -> "three"; case 4, 5, 6 -> "four or five or six"; default -> "unknown"; }; }
Or, like this, mix the arrow syntax with yield.
private static String getNumberViaCaseL2(int number) { return switch (number) { case 1, 2 -> "one or two"; case 3 -> "three"; case 4, 5, 6 -> { int i = 0; i++; yield "four or five or six :" + 1; } default -> "unknown"; }; }
Java 14
The switch expression becomes Java 14 – JEP 361 Standard features of.
be careful
For a complete example, read this Java 13 Switch Expressions.
JEP-355 text block (Preview)
The JEP finally introduces multi line string text, text block.
PS this is the preview language function in Java 13
Before Java 13
String html ="<html>\n" + " <body>\n" + " <p>Hello, World</p>\n" + " </body>\n" + "</html>\n"; String json ="{\n" + " \"name\":\"mkyong\",\n" + " \"age\":38\n" + "}\n";
Now Java 13
String html = """ <html> <body> <p>Hello, World</p> </body> </html> """; String json = """ { "name":"mkyong", "age":38 } """;
Further reading
More multiline strings, examples of text blocks
be careful
This text block is in Java 14 With second Preview – JEP 368 , two new escape sequences were added:
- \< end of line > prohibit line termination.
- \s is translated into a space.
To enable the Java 13 preview feature:
javac --enable-preview --release 13 Example.java java --enable-preview Example
Download source code
$ git clone https://github.com/mkyong/core-java
$ cd java-13
reference
- OpenJDK 13 project
- Oracle – Java 13 coming!
- cl4cds
- Java version history
- Java 13 switch expression
- Java 13 data sharing with application classes
- Java 13 text block
- What are the new features of Java security?
- Java multiline string, text block example
Translated from: https://mkyong.com/java/what-is-new-in-java-13/