We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
{
Getting The Most From
Modern Java Presented by Simon Ritter, Deputy CTO | Azul Systems Inc. Introduction
Java has changed…
…a lot • Six-month release cadence • Seven releases since JDK 9 • More features being delivered faster than ever before
2 Incubator Modules • Defined by JEP 11 • Non-final APIs and non-final tools ‒ Deliver to developers to solicit feedback ‒ Can result in changes or even removal ‒ First example: HTTP/2 API (Introduced in JDK 9, final in JDK 11)
3 Preview Features • Defined by JEP 12 • New feature of the Java language, JVM or Java SE APIs ‒ Fully specified, fully implemented but not permanent ‒ Solicit developer real-world use and experience ‒ May lead to becoming a permanent feature in future release • Must be explicitly enabled ‒ javac --release 14 --enable-preview ... ‒ java --enable-preview ... • Preview APIs ‒ May be required for a preview language feature ‒ Part of the Java SE API (java or javax namespace)
4 JDK 12 Switch Expressions (Preview) • Switch construct was a statement ‒ No concept of generating a result that could be assigned • Rather clunky syntax ‒ Every case statement needs to be separated ‒ Must remember break (default is to fall through) ‒ Scope of local variables is not intuitive
6 Old-Style Switch Statement int numberOfLetters; switch (day) { case MONDAY: case FRIDAY: case SUNDAY: numberOfLetters = 6; break; case TUESDAY: numberOfLetters = 7; break; case THURSDAY: case SATURDAY: numberOfLetters = 8; break; case WEDNESDAY: numberOfLetters = 9; break; default: throw new IllegalStateException("Huh?: " + day); };
7 New-Style Switch Expression
int numberOfLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; default -> throw new IllegalStateException("Huh?: " + day); }; New Old-Style Switch Expression
int numberOfLetters = switch (day) {
case MONDAY: case FRIDAY: case SUNDAY: break 6; case TUESDAY break 7; case THURSDAY case SATURDAY break 8; case WEDNESDAY break 9; default: throw new IllegalStateException("Huh?: " + day); }; Streams
• New collector, teeing
‒ teeing(Collector, Collector, BiFunction) • Collect a stream using two collectors • Use a BiFunction to merge the two collections
11 JDK 13 Text Blocks (Preview) String webPage = """ <html> <body> <p>My web page</p> incidental white space </body> </html>"""; [Link](webPage);
$ java WebPage <html> <body> <p>My web page</p> </body> </html> $ Text Blocks (Preview) String webPage = """ <html> Intentional indentation <body> <p>My web page</p> </body> incidental white space </html> """; [Link](webPage); $ java WebPage <html> <body> <p>My web page</p> </body> </html> Additional blank line $ Switch Expression
int numberOfLetters = switch (day) {
case MONDAY: case FRIDAY: case SUNDAY: break 6; case TUESDAY break 7; case THURSDAY case SATURDAY break 8; case WEDNESDAY break 9; default: throw new IllegalStateException("Huh?: " + day); }; Switch Expression
int numberOfLetters = switch (day) {
case MONDAY: case FRIDAY: case SUNDAY: yield 6; case TUESDAY yield 7; case THURSDAY case SATURDAY yield 8; case WEDNESDAY yield 9; default: throw new IllegalStateException("Huh?: " + day); }; JDK 14 Simple Java Data Class class Point { private final double x; private final double y;
public Point(double x, double y) {
this.x = x; this.y = y; }
public double x() {
return x; }
public double y() {
return y; } } 18 Records (Preview)
record Point(double x, double y) { }
record Range(int low, int high) {
public Range { // Compact constructor if (low > high) throw new IllegalArgumentException("Bad values"); } }
19 Record Additional Details • Compact constructor can only throw unchecked exception ‒ Syntax does not allow for specifying a checked exception • Object methods equals(), hashCode() and toString() can be overridden • The base class of all records is [Link] ‒ This is an example of a preview feature Java SE API ‒ Records cannot sub-class (but may implement interfaces) • Records do not follow the Java bean pattern ‒ x() not getX() in previous example • Instance fields cannot be added to a record ‒ Static fields can • Records can be generic 20 Using instanceof
if (obj instanceof String) {
String s = (String)obj; [Link]([Link]()); }
21 Pattern Matching instanceof (Preview)
if (obj instanceof String s)
[Link]([Link]()); else // Use of s not allowed here
if (obj instanceof String s && [Link]() > 0)
[Link]([Link]());
// Compiler error if (obj instanceof String s || [Link]() > 0) [Link]([Link]());
22 Pattern Matching instanceof (Preview)
if (!(o instanceof String s && [Link]() > 3)
return;
[Link]([Link]());
23 Text Blocks • Second preview • Two new escape sequences
String continuous = """This line will not \
contain a newline in the middle and solves the extra blank line issue \ """;
String endSpace = """This line will not \s
lose the trailing spaces \s"""; Helpful NullPointerException • Who's never had an NullPointerException?
a.b.c.i = 99;
Exception in thread "main" [Link]
at [Link]([Link])
Exception in thread "main" [Link]:
Cannot read field "c" because "a.b" is null at [Link]([Link])
• Enabled with -XX:+ShowCodeDetailsInExceptionMessages
25 JDK 15 Java Inheritance • A class (or interface) in Java can be sub-classed by any class ‒ Unless it is marked as final
Shape
Triangle Square Pentagon
27 Sealed Classes (JEP 360) • Preview feature • Sealed classes allow control over which classes can sub-class a class ‒ Think of final as the ultimate sealed class
• Although called sealed classes, this also applies to interfaces
28 Sealed Classes (JEP 360) • Uses contextual keywords ‒ New idea replacing restricted identifiers and keywords ‒ sealed, permits and non-sealed • Classes must all be in the same package or module
public sealed class Shape permits Triangle, Square, Pentagon { ... }
Shape X
Triangle Square Pentagon Circle
29 Sealed Classes (JEP 360) • All sub-classes must have inheritance capabilities explicitly specified
// Restrict sub-classes to defined set
public sealed class Triangle permits Equilateral, Isosoles extends Shape { ... }
// Prevent any further sub-classing
public final class Square extends Shape { ... }
// Allow any classes to sub-class this one (open)
public non-sealed class Pentagon extends Shape { ... }
30 Contextual Keyword Humour
int non = 2; int sealed = 1;
var var = non-sealed;
31 Hidden Classes (JEP 371) • JVM rather than language-level feature • Classes that cannot be used directly by the bytecodes of other classes • Several situations where bytecodes generated at runtime ‒ Use of invokedynamic bytecode ‒ Lambdas are a good example ‒ Mostly bound to static class (not for use elsewhere) ‒ Often only used for short time • Hidden classes can only be accessed via reflection ‒ Primarily intended for framework developers
32 Records (Second Preview) • Record fields are now (really) final ‒ Cannot be changed via reflection (will throw IllegalAccessException) • Native methods now explicitly prohibited ‒ Could introduce behaviour dependent on external state
33 Records (Second Preview) • Local records ‒ Like a local class ‒ Implicitly static
List<Seller> findTopSellers(List<Seller> sellers, int month) {
// Local record record Sales(Seller seller, double sales) {}
34 Records (Second Preview) • Records work with sealed classes (interfaces)
public sealed interface Car permits RedCar, BlueCar { ... }
public record RedCar(int w) implements Car { ... }
public record BlueCar(long w, int c) implements Car { ... }
35 JDK 16 Pattern Matching instanceof (JEP 394) • Now final, i.e. part of the Java SE specification • Two minor changes to previous iterations ‒ Pattern variables are no longer implicitly final ‒ Compile-time error to compare an expression of type S against a pattern of type T where S is a sub-type of T
if (r instanceof Rectangle rect) { [Link](rect); } }
| Error: | pattern type Rectangle is a subtype of expression type Rectangle | if (r instanceof Rectangle rect) { | ^-------------------------^ 37 Add UNIX-Domain Socket Channels • Add UNIX_AF socket channels ‒ Used for IPC on UNIX-based OSs and Windows • Better security and performance than TCP/IP loopback connections ‒ Behaviour is identical • No constructor, use factory methods var unix = [Link]("/tmp/foo");
38 Streams mapMulti • Similar to flatMap ‒ Each element on the input stream is mapped to zero or more elements on the output stream ‒ Difference is that a mapping can be applied at the same time ‒ Uses a BiConsumer
39 Vector API (JEP 338) • Incubator module (not part of the Java SE specification) • API to express vector computations ‒ Compile at runtime to optimal hardware instructions ‒ Deliver superior performance to equivalent scalar operations
• Ideally, this would not be necessary
‒ Compiler should identify where vector operations can be used
40 Vector API (JEP 338) void scalarComputation(float[] a, float[] b, float[] c) { for (int i = 0; i < [Link]; i++) c[i] = (a[i] * a[i] + b[i] * b[i]) * -1.0f; }
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_256;
void vectorComputation(float[] a, float[] b, float[] c) {
for (int i = 0; i < [Link]; i += [Link]()) { var m = [Link](i, [Link]); var va = [Link](SPECIES, a, i, m); var vb = [Link](SPECIES, b, i, m); var vc = [Link](va). add([Link](vb)). neg(); [Link](c, i, m); } } 41 Foreign-Memory Access API (JEP 393) • Introduced in JDK 14, now third incubator iteration • API for safe and efficient access to memory outside of the Java heap • MemorySegment ‒ Models a contiguous area of memory • MemoryAddress ‒ Models an individual memory address (on or off heap) • MemoryLayout ‒ Programmatic description of a MemorySegment
try (MemorySegment segment = [Link](100)) {
for (int i = 0; i < 25; i++) [Link](segment, i * 4, i); } 42 Foreign-Memory Access API (JEP 393) • Example using MemoryLayout and VarHandle ‒ Simpler access of structured data
for (int i = 0; i < [Link]().getAsLong(); i++) [Link](segment, (long) i, i); } 43 Foreign Linker API (JEP 389): Incubator • Provides statically-typed, pure-Java access to native code ‒ Works in conjunction with the Foreign Memory Access API ‒ Initially targeted at C native code. C++ should follow • More powerful when combined with Project Panama jextract command
public static void main(String[] args) throws Throwable {
var linker = [Link](); var lookup = [Link](); // get a native method handle for 'getpid' function var getpid = [Link]([Link]("getpid").get(), [Link]([Link]), [Link](CLinker.C_INT));
[Link]((int)[Link]()); } 44 Warnings for Value-Based Classes • Part of Project Valhalla, which adds value-types to Java ‒ Introduces the concept of primitive classes • Primitive wrapper classes (Integer, Float, etc.) designated value-based ‒ Constructors were deprecated in JDK 9 ‒ Now marked as for removal ‒ Attempting to synchronize on an instance of a value-based class will issue a warning
45 Strongly Encapsulate JDK Internals By Default • Encapsulation of JDK internal APIs started in JDK 9 ‒ Part of modularity (Project Jigsaw) • Side effect was the potential to break many applications and frameworks ‒ Spring, etc. • The big kill switch was included to get round this ‒ --illegal-access ‒ Four options: permit, warn, debug, deny ‒ Until now default has been permit ‒ New default is deny • Critical internal APIs are still not encapsulated ‒ Including [Link]
46 Summary Zulu Enterprise • Enhanced build of OpenJDK source code Fully TCK tested JDK 6, 7, 8, 11 and 13 TLS1.3, Flight Recorder backports • Wide platform support: Intel 64-bit Windows, Mac, Linux Intel 32-bit Windows and Linux • Real drop-in replacement for Oracle JDK Many enterprise customers No reports of any compatibility issues
48 Conclusions • The six-month release cycle is working well • JDK 12 to JDK 16 contains lots of great new features • Start preparing for JDK 17, the next LTS ‒ Test with JDK 16 • Use Zulu builds of OpenJDK if you want to deploy to production