The document discusses new features in Java releases from JDK 13 to JDK 15, including syntax changes like switch expressions and text blocks, API changes like helpful NullPointerExceptions and reimplementing sockets, and improvements to garbage collectors like ZGC and NUMA-aware memory allocation for G1. It provides code examples to demonstrate the new features and explains their motivations and impacts.
6. JDK 13 (2019-09-17)
• JEP 350: Dynamic CDS Archives
• JEP 351: ZGC: Uncommit Unused Memory
• JEP 353: Reimplement the Legacy Socket API
• JEP 354: Switch Expressions (Preview)
• JEP 355: Text Blocks (Preview)
6
7. JDK 14 (2020-03-17)
• JEP 305: Pattern Matching for instanceof (Preview)
• JEP 343: Packaging Tool (Incubator)
• JEP 345: NUMA-Aware Memory Allocation for G1
• JEP 349: JFR Event Streaming
• JEP 352: Non-Volatile Mapped Byte Buffers
• JEP 358: Helpful NullPointerExceptions
• JEP 359: Records (Preview)
• JEP 362: Deprecate the Solaris and SPARC Ports
7
8. JDK 14 (2020-03-17) cont.
• JEP 361: Switch Expressions (Standard)
• JEP 363: Remove the CMS Garbage Collector
• JEP 364: ZGC on macOS
• JEP 365: ZGC on Windows
• JEP 366: Deprecate the ParallelScavenge +
SerialOld GC combination
• JEP 367: Remove the Pack200 Tools and API
• JEP 368: Text Blocks (Second Preview)
• JEP 370: Foreign-Memory Access API (Incubator)
8
9. JDK 15 (2020-09-15)
• JEP 339: Edwards-Curve Digital Signature
Algorithm (EdDSA)
• JEP 360: Sealed Classes (Preview)
• JEP 371: Hidden Classes
• JEP 372: Remove the Nashorn JavaScript Engine
• JEP 373: Reimplement the Legacy DatagramSocket
• JEP 374: Disable and Deprecate Biased Locking
• JEP 375: Pattern Matching for instanceof (Preview)
9
10. JDK 15 (2020-09-15) cont.
• JEP 377: ZGC: A Scalable Low-Latency GC
• JEP 378: Text Blocks
• JEP 379: Shenandoah: A Low-Pause-Time GC
• JEP 381: Remove the Solaris and SPARC Ports
• JEP 383: Foreign-Memory Access API (Incubator)
• JEP 384: Records (Preview)
• JEP 385: Deprecate RMI Activation for Removal
10
12. Switch Expressions
• Preview: JEP 325 (JDK12), JEP 354 (JDK13)
• Standard: JEP 361 (JDK14)
• To extend switch to be either a statement or an
expression so that both forms can use either
traditional labels (with fall through)
case ... :
or new labels (with no fall through)
case ... ->
, with a further new statement for yielding a value
from a switch expression.
12
13. Switch Expressions Syntax
T result = switch(arg) {
case label1 -> expression1;
case label2 -> expression2;
default -> expression3;
}
13
14. Switch Statement - Before
void showNumber(int i) {
switch(i) {
case 0: System.out.println("Zero"); break;
case 1: System.out.println("One"); break;
case 2: System.out.println("Two"); break;
default: System.out.println(“Others"); break;
}
}
14
15. Switch Statement - After
void showNumber(int i) {
switch(i) {
case 0 -> System.out.println("Zero");
case 1 -> System.out.println("One");
case 2 -> System.out.println("Two");
default -> System.out.println("Others");
}
}
15
17. Switch Expressions Assignment
enum Month {
JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
}
int getDay(Month month) {
int result = switch(month) {
case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> 31;
case APR, JUN, SEP, NOV -> 30;
case FEB -> 28;
};
return result;
}
17
19. Switch Expressions - yield
• If a full block is needed, we can use the new yield
statement to yield a value, which becomes the
value of the enclosing switch expression.
• When using a traditional switch block, values can
also be yielded by using the new yield statement.
19
22. Text Blocks
• Preview: JEP 326 (JDK12), JEP 355 (JDK13),
JEP 368 (JDK14)
• Standard: JEP 378 (JDK15)
• A multi-line string literal that avoids the need for
most escape sequences, automatically formats the
string in a predictable way, and gives the
developer control over the format when desired.
22
30. Pattern Matching for instanceof
• Preview: JEP 305 (JDK14), JEP 375 (JDK15)
• It enhances instanceof operators to allow
common logic in a program, namely the
conditional extraction of components from
objects, to be expressed more concisely and safely
30
31. Pattern Matching - Before
if (obj instanceof String) { // check
String s = (String) obj; // assign + cast
System.out.println("String: " + s);
} else if (obj instanceof Integer) {
Integer i = (Integer) obj;
System.out.println("Integer: " + i);
} else if (obj instanceof Map) {
Map m = (Map) obj;
System.out.println("Map: " + m);
}
31
32. Pattern Matching - After
if (obj instanceof String s) { //only use s here
System.out.println("String: " + s);
} else if (obj instanceof Integer i) { //no s here
System.out.println("Integer: " + i);
} else if (obj instanceof Map m) {
System.out.println("Map: " + m);
}
32
33. Pattern Matching - Conditions
if (obj instanceof String s && s.length() > 1) {
System.out.println("Text: " + s);
} // PASS
if (obj instanceof String s || s.length() > 1) {
System.out.println("Text: " + s);
} // ERROR
33
35. Pattern Matching - equals()
public class TestClass {
private String s;
public TestClass(String s) { this.s = s; }
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
return o instanceof TestClass testClass &&
testClass.s.equals(this.s);
}
}
35
36. Records
• Preview: JEP 359 (JDK14), JEP 384 (JDK15)
• Classes that act as transparent carriers for
immutable data. Records can be thought of as
nominal tuples.
• This new kind of class is to declare that a small
group of variables is to be regarded as a new kind
of entity. A record declares its state (the group of
variables) and commits to an API that matches
that state.
36
37. Records - Before
class Point {
private final int x, y;
Point(int x, int y) { this.x = x; this.y = y; }
int x() { return x; }
int y() { return y; }
public boolean equals(Object o) {
return o instanceof Point
&& ((Point) o).x == x
&& ((Point) o).y == y;
}
public int hashCode() { return Objects.hash(x, y); }
public String toString() {
return String.format("Point[x=%d, y=%d]", x, y);
}
}
37
38. Records - After
• The declaration of a record specifies a name, a
header and a body. The header lists the
components of the record, which are the variables
that make up its state.
record Point(int x, int y) {
// body
}
38
39. Records - Standard Members
• For each component in the header: a public
accessor method with the same name and return
type as the component, and a private final field
with the same type as the component
• A canonical constructor whose signature is the
same as the header
• equals and hashCode methods which say that two
records are equal if they are of the same type/value
• A toString method that returns a string
representation of all the record components along
with their names
39
41. Records - Restrictions
• A record doesn't have an extends clause. The
superclass is always java.lang.Record, like enum
• A record is implicitly final and cannot be abstract
• A record cannot explicitly declare instance fields,
and cannot contain instance initializers.
• The implicitly declared fields are final
• A record cannot declare native methods.
41
42. Records - Behaviors
• Instantiated with the new keyword
• Can be declared top level or nested
• Can declare static methods/fields/initializers
• Can declare instance methods
• Can implement interfaces
• Can declare nested types, including nested records
• Can be annotated
42
43. Records with static Members
record Point(int x, int y) implements Serializable {
private static int counter;
public static int getCounter() { return counter; }
public static void addCounter() { counter++; }
public int plusX() { return counter * x;}
}
43
45. Records with Nested Builder
record Point(int x, int y) {
public static class Builder {
private int x, y;
public Builder withX(int x) { this.x = x; return this; }
public Builder withY(int y) { this.y = y; return this; }
public Point build() { return new Point(x, y);}
}
public static Builder newBuilder() { return new Builder(); }
}
Point p = Point.newBuilder().withX(2).withY(3).build();
45
47. Sealed Classes
• Preview: JEP 360 (JDK15)
• Sealed classes and interfaces restrict which other
classes or interfaces may extend or implement
them.
• Allow the author of a class or interface to control
which code is responsible for implementing it.
• Provide a more declarative way than access
modifiers to restrict the use of a superclass
• Support future directions in pattern matching by
underpinning the exhaustive analysis of patterns
47
48. Sealed Classes Syntax
public sealed interface Shape
permits Circle, Rectangle, Square {}
public final class Circle implements Shape {}
public sealed class Rectangle implements Shape
permits TransparentRectangle {}
public final class TransparentRectangle
extends Rectangle {}
public record Square(int x, int y)
implements Shape {}
48
52. Helpful NullPointerException
• It’s very hard to troubleshoot the root cause when
NullPointerExceptions are thrown:
• a.b.c.i = 99
• a[i][j][k] = 99
• a.i = b.j
• a[i][j] = b[x][y]
• a.getB().getC().getD()
Exception java.lang.NullPointerException
at (xxxx:10)
52
53. Helpful NullPointerException
• a.b.c.i = 99
Exception in thread "main" java.lang.NullPointerException:
Cannot read field "c" because "a.b" is null
• a[i][j][k] = 99
Exception in thread "main" java.lang.NullPointerException:
Cannot load from object array because "a[i][j]" is null
• a.i = b.j
Exception in thread "main" java.lang.NullPointerException:
Cannot read field "j" because "b" is null
• a[i][j] = b[x][y]
Exception in thread "main" java.lang.NullPointerException:
Cannot invoke "java.lang.Integer.intValue()" because "j"
is null
53
54. Helpful NullPointerException
• The first part is the consequence of the NPE. It
says which action could not be performed
because a bytecode instruction popped a null
reference from the operand stack.
• The second part is the reason for the NPE. It
recreates the part of the source code that pushed
the null reference on to the operand stack.
54
57. Reimplement Socket
• The implementations of java.net.Socket and
java.net.ServerSocket have been reimplemented.
The original used PlainSocketImpl from JDK1.0.
Now they uses NioSocketImpl
• Adding -Djdk.net.usePlainSocketImpl in JVM
options can let you use the old version of Socket
API.
57
58. Reimplement DatagramSocket
• Replace the underlying implementations of the
java.net.DatagramSocket & java.net.MulticastSocket
APIs with simpler and more modern
implementations that are easy to maintain and
debug.
58
59. Hidden Classes
• A kind of classes cannot be used directly by the
bytecode of other classes.
• They are intended for use by frameworks that
generate classes at run time and use them
indirectly, via reflection.
• A hidden class may be defined as a member of an
access control nest, and may be unloaded
independently of other classes.
59
61. Numa-Aware Memory Allocation for G1
• Improve G1 performance on large machines by
implementing NUMA-aware memory allocation
61
62. ZGC
• JEP 333: ZGC: A Scalable Low-Latency Garbage
Collector (Experimental) (JDK11)
• JEP 351: ZGC: Uncommit Unused Memory
• JEP 364: ZGC on macOS (JDK14)
• JEP 365: ZGC on Windows (JDK14)
• JEP 377: ZGC: A Scalable Low-Latency Garbage
Collector (JDK15)
62
63. ZGC
• It supports TB-level (8MB~16TB) GC with very low
pause time (<10ms) by using colored pointer and
read barriers, developed by Oracle.
• ZGC is enabled now via the following command-
line option: -XX:+UseZGC
• Because ZGC is a product (non-experimental)
feature, it means the option
-XX:+UnlockExperimentalVMOptions
will no longer be needed.
63
64. Shenandoah GC
• It is a low-pause-time garbage collector from Red
Hat, and supports AArch64 and Amd64. It is also
low-pause-time. Unlike ZGC based on colored
pointers, Shenandoah GC uses brooks pointers.
• Shenandoah GC is enabled now via the following
command-line option: -XX:+UseShenandoahGC
• Because Shenandoah GC is a product (non-
experimental) feature, it means the option
-XX:+UnlockExperimentalVMOptions
will no longer be needed.
64
66. Removal/Deprecation of GC
• Remove the Concurrent Mark Sweep (CMS)
Garbage Collector in JEP 363 (JDK14)
• Deprecated in JEP 291 (JDK9)
• Deprecate the ParallelScavenge + SerialOld GC
Combination in JEP 366 (JDK14)
• The pairing of the parallel young generation GC
and the serial old GC, enabled with
-XX:+UseParallelGC -XX:-UseParallelOldGC
• Very little used but requires a significant
amount of maintenance effort
66
67. Removal/Deprecation of APIs
• Solaris and SPARC Ports
• Deprecated in JEP 362 (JDK14)
• Removed in JEP 381 (JDK15)
• Pack200 Tools and API
• Introduced in JSR 200 (Java SE 5.0)
• Last used in JDK8
• Deprecated in JEP 336 (JDK11)
• Removed in JEP 367 (JDK14)
67
68. Removal/Deprecation of APIs
• Nashorn JavaScript Engine
• Introduced in JEP 174 (JDK8)
• Deprecated in JEP 335 (JDK11)
• Removed in JEP 372 (JDK15)
• Disable and Deprecate Biased Locking (JDK 15)
• RMI Activation mechanism (java.rmi.activation)
• Rarely used in these years
• Optional since JDK 8
• Deprecated in JEP 385 (JDK15)
68
69. Incubator - Packaging Tool
• Create a tool for packaging self-contained Java
applications
• Support native packaging formats to give end
users a natural installation experience
• Windows: msi and exe
• macOS: pkg and dmg
• Linux: deb and rpm
• Allow launch-time parameters to be specified at
packaging time
69
71. Foreign-Memory Access API
• Introduce an API to allow Java programs to safely
and efficiently access foreign memory outside of
the Java heap
• The foreign-memory access API introduces three
main abstractions:
• MemorySegment
• MemoryAddress
• MemoryLayout
71
72. Foreign-Memory Access API
VarHandle handle =
MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder())
try (MemorySegment seg = MemorySegment.allocateNative(100)) {
MemoryAddress base = seg.baseAddress();
for (int i = 0; i < 25; i++) {
MemoryAddress offset = base.addOffset(i * 4);
handle.set(offset, i * 3);
System.out.println(
String.format("i: %d, o: %d, v: %d”,
i, offset.segmentOffset(), handle.get(offset)));
}
}
72
75. JDK 16 (2021-03-16)
• JEP 338: Vector API (Incubator)
• JEP 347: Enable C++14 Language Features
• JEP 357: Migrate from Mercurial to Git
• JEP 369: Migrate to GitHub
• JEP 376: ZGC: Concurrent Thread-Stack Processing
• JEP 380: Unix-Domain Socket Channels
• JEP 386: Alpine Linux Port
75
76. JDK 16 (2021-03-16) cont.
• JEP 387: Elastic Metaspace
• JEP 388: Windows/AArch64 Port
• JEP 392: Packaging Tool
• JEP 393: Foreign-Memory Access API (3rd Incubator)
• JEP 394: Pattern Matching for instanceof
• JEP 395: Records
76