SlideShare a Scribd company logo
From JDK 9 to 16
New Java Workshop
Presented by Simon Ritter, Deputy CTO | Azul Systems Inc.
Introduction
2
•Six-month release cadence
•Seven releases since JDK 9
•More features being delivered faster than ever before
Java has changed…
…a lot
Incubator Modules
3
• 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)
Preview Features
4
• 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)
JDK 9
Project Jigsaw And Modules
Why Do We Need Modularity in Java?
7
• JDK 1.0
‒ 122 library classes for simplifying application development
• JDK 8.0
‒ Over 4,500 public classes in the rt.jar file
• JDK 9
‒ 27 Java SE modules, 48 JDK modules
• Two sides to modularity:
1. JDK core libraries
2. Application code
Module Fundamentals
8
• Module is a grouping of code
‒ For Java this is a collection of packages
• Modules can contain other things
‒ Native code
‒ Resources
‒ Configuration data
com.azul.zoop
com.azul.zoop.alpha.Name
com.azul.zoop.alpha.Position
com.azul.zoop.beta.Animal
com.azul.zoop.beta.Reptile
com.azul.zoop.theta.Zoo
com.azul.zoop.theta.Lake
Module Declaration
module com.azul.zoop {}
module-info.java
com/azul/zoop/alpha/Name.java
com/azul/zoop/alpha/Position.java
com/azul/zoop/beta/Animal.java
com/azul/zoop/beta/Reptile.java
com/azul/zoop/theta/Zoo.java
com/azul/zoop/theta/Lake.java
Module Dependencies
module com.azul.zoop {
requires com.azul.zeta;
} com.azul.zoop
com.azul.zeta
Module Dependencies
module com.azul.zapp {
requires com.azul.zoop;
requires java.sql;
}
com.azul.zapp
com.azul.zoop java.sql
Module Dependency Graph
com.azul.zapp
java.base
java.sql
com.azul.zoop
com.azul.zeta
java.xml java.logging
explicit
implicit
Module Dependency Graph
13
• No missing dependencies
• No cyclic dependencies
• No split packages
Readability v. Dependency
com.azul.zapp
java.sql
java.logging
module java.sql {
requires transitive java.logging;
}
Driver d = …
Logger l = d.getParentLogger();
l.log(“azul’);
Implied readability
Module Implied Readability Graph
com.azul.zapp
java.base
java.sql
com.azul.zoop
com.azul.zeta
java.xml java.logging
explicit
implicit
implied
Package Visibility
module com.azul.zoop {
requires com.azul.zeta;
exports com.azul.zoop.alpha;
exports com.azul.zoop.beta to com.azul.zapp;
}
com.azul.zoop
com.azul.zoop.alpha
com.azul.zoop.beta
com.azul.zoop.theta
com.azul.zapp only
More Package Visibility
open module com.azul.zoop {
requires com.azul.zeta;
}
com.azul.zoop
com.azul.zoop.alpha
com.azul.zoop.beta
com.azul.zoop.theta
com.azul.zoop.alpha
com.azul.zoop.beta
com.azul.zoop.theta
REFLECTION
IMPORT
Even More Package Visibility
module com.azul.zoop {
requires com.azul.zeta;
exports com.azul.zoop.alpha;
exports com.azul.zoop.beta to com.azul.zapp;
opens com.azul.theta;
}
com.azul.zoop
com.azul.zoop.theta
REFLECTION
IMPORT
com.azul.zoop.alpha
com.azul.zoop.beta
com.azul.zapp only
Restricted Keywords
module
requires requires;
exports exports to to;
module {
opens opens;
}
Accessibility
• For a package to be visible
‒ The package must be exported by the containing module
‒ The containing module must be read by the using module
• Public types from those packages can then be used
com.azul.zoop
com.azul.zapp
reads
Using Modules
Module Path
$ javac –modulepath dir1:dir2:dir3
Compilation With Module Path
$ javac –-module-path mods –d mods 
src/module-info.java 
src/com/azul/zoop/alpha/Name.java
mods/module-info.class
mods/com/azul/zoop/alpha/Name.class
src/module-info.java
src/com/azul/zoop/alpha/Name.java
Application Execution
• -p is the abbreviation of --module-path
$ java –p mods –m com.azul.zapp/com.azul.zapp.Main
Azul application initialised!
module name main class
Packaging With Modular JAR Files
mods/module-info.class
mods/com/azul/zapp/Main.class
$ jar --create --file=mylib/zapp.jar 
--main-class=com.azul.zapp.Main 
-C mods .
module-info.class
com/azul/zapp/Main.class
zapp.jar
Application Execution (JAR)
$ java –p mylib:mods –m com.azul.zapp
Azul application initialised!
Linking
Modular run-time
image
…
conf
bin
jlink
$ jlink --module-path $JDKMODS 
--add-modules java.base –-output myimage
$ myimage/bin/java –-list-modules
java.base@9.0
Linking An Application
$ jlink --module-path $JDKMODS:$MYMODS 
--add-modules com.azul.zapp –-output myimage
$ myimage/bin/java –-list-modules
java.base@9
java.logging@9
java.sql@9
java.xml@9
com.azul.zapp@1.0
com.azul.zoop@1.0
com.azul.zeta@1.0
The Implications Of jlink
• "Write once, run anywhere"
 Long term Java slogan, mainly held true
• jlink generated runtime may not include all Java SE modules
‒ But is still a conforming Java implementation
‒ To conform to the specification, the runtime:
 Must include the java.base module
 If other modules are included, all transitive module dependencies must also be
included
 Defined as a closed implementation
Application Migration
Typical Application (JDK 8)
jar
jar
jar
JDK
jar
jar
jar
jar jar
jar
jar
jar
jar
Classpath
Typical Application (JDK 9)
jar
jar
jar
module
java.base
module
java.desktop
module
java.datatransfer
module
java.xml
jar
jar
jar
jar jar
jar
jar
jar
jar
Unnamed
module
Sample Application
myapp.jar
libgl.jar
mylib.jar
gluegen.jar jogl.jar
module
java.base
module
java.desktop
module
java.datatransfer
module
java.xml
Run Application With Classpath
$ java –classpath 
lib/myapp.jar: 
lib/mylib.jar: 
lib/libgl.jar: 
lib/gluegen.jar: 
lib/jogl.jar: 
myapp.Main
Sample Application
module
myapp.jar
libgl.jar
module
mylib.jar
gluegen.jar jogl.jar
module
java.base
module
java.desktop
module
java.datatransfer
module
java.xml
Application module-info.java
module myapp {
requires mylib;
requires java.base;
requires java.sql;
requires libgl; ????
requires gluegen; ????
requires jogl; ????
}
Sample Application
module
myapp.jar
module
libgl.jar
module
mylib.jar
module
gluegen.jar
module
jogl.jar
module
java.base
module
java.desktop
module
java.datatransfer
module
java.xml
Automatic Modules
38
• Real modules
• Simply place unmodified jar file on module path
‒ Rather than classpath
• No changes to JAR file
• Module name derived from JAR file name
• Exports all its packages
‒ No selectivity
• Automatically requires all modules on the module path
Application Module Dependencies
module
myapp.jar
module
libgl.jar
module
mylib.jar
module
gluegen.jar
module
jogl.jar
module
java.base
module
java.desktop
module
java.datatransfer
module
java.xml
Implicit
Explicit
Run Application With Modules
$ java –classpath 
lib/myapp.jar: 
lib/mylib.jar: 
lib/libgl.jar: 
lib/gluegen.jar: 
lib/jogl.jar: 
myapp.Main
$ java –p mylib:lib –m myapp
Migrating Applications To The
Java Platform Module System
Migration Guidance From Oracle
"Clean applications that just depend on java.se
should just work"
Migrating Applications to JPMS
43
• Initially, leave everything on the classpath
• Anything on the classpath is in the unnamed module
‒ All packages are exported
‒ The unnamed module depends on all modules
• Migrate to modules as required
‒ Try automatic modules
‒ Move existing jar files from classpath to modulepath
Classpath v Modulepath
classpath
modulepath
Unnamed module
jar jar
jar
module-info.class
jar
module-info.class
jar
Automatic module
module-info.class
Reversing Encapsulation
• "The Big Kill Switch"
--illegal-access
• Four options:
‒ permit (current default)
‒ warn
‒ debug
‒ deny (JDK 16 default)
Reversing Encapsulation
• Big kill switch overrides encapsulation
‒ From the unnamed module (i.e. classpath)
‒ Allows unlimited refective access to named modules
 Not from named modules
• Warning messages written to error stream
• Useful to understand use of --add-exports and --add-opens when
migrating to named modules
Reversing Encapsulation
47
• Allowing direct access to encapsulated APIs
‒ --add-exports
• Allowing reflective access to encapsulated APIs
‒ --add-opens
--add-exports java.management/com.sun.jmx.remote.internal=mytest
--add-exports java.management/sun.management=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
Finding Dependencies: jdeps
> jdeps --module-path /opt/javafx-sdk-11/lib
--add-modules=javafx.controls --list-deps FlightTracker.jar
JDK removed internal API/com.sun.media.jfxmediaimpl.platform.ios
java.base
java.datatransfer
java.desktop/java.awt.dnd.peer
java.desktop/sun.awt
java.desktop/sun.awt.dnd
java.desktop/sun.swing
java.logging
java.scripting
java.sql
java.xml
jdk.jsobject
jdk.unsupported
jdk.unsupported.desktop
jdk.xml.dom
JDK 10
Java Storage Basics
50
• Fields (instance and static)
‒ Part of an object, exist for the lifetime of an object
‒ Initialisation guaranteed by compiler
• Local variables
‒ Scoped to region of code (method, statement, block)
‒ Initialisation not guaranteed
‒ Cheap when allocated on the stack
‒ Name and use is often more important than the type
Local Variable Type Inference
• Why?
‒ JavaScript has it so it must be good
‒ Streams hide intermediate types
‒ Why not expand this elsewhere?
‒ var can make code more concise
 Without sacrificing readability
List l = names.stream() // Stream<String>
.filter(s -> s.length() > 0) // Stream<String>
.map(s -> getRecord(s)) // Stream<Record>
.collect(toList()); // ArrayList<Record>
Simple Uses of Local Variables
ArrayList<String> nameList = new ArrayList<String>();
List<String> userList = new ArrayList<>();
Stream<String> stream = userList.stream();
for (String name : userList) {
...
}
for (int i = 0; i < 10; i++) {
...
}
Simple Uses of Local Variable Type Inference
var userList = new ArrayList<String>(); // Infers ArrayList<String>
var stream = userList.stream(); // Infers Stream<String>
for (var name : userList) { // Infers String
...
}
for (var i = 0; i < 10; i++) { // Infers int
...
}
Simple Uses of var
• Clearer try-with-resources
try (InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader =
new InputStreamReader(inputStream, UTF_8);
BufferedReader bufferedReader =
new BufferedReader(inputStreamReader)) {
// Use bufferedReader
}
Simple Uses of var
• Clearer try-with-resources
try (var inputStream = socket.getInputStream();
var inputStreamReader = new inputStreamReader(inputStream, UTF_8);
var bufferedReader = new BufferedReader(inputStreamReader)) {
// Use bufferedReader
}
More Typing With Less Typing
• Java is still statically typed
var name = "Simon"; // Infers String, so name is String
name = "Dylan"; // Still String
name = 42; // Not a String
error: incompatible types: int cannot be converted to String
Final and Non-Final
57
• var simply indicates the compiler infers the type
• Use of var does not make a variable final
• Still need final
• No shortcut for final var (like val)
‒ How often do you make local-variables final?
var name = "Simon";
name = "Dylan"; // name is not final
final var name = "Simon";
Action At A Distance
var l = new ArrayList<String>();
var s = l.stream();
// Lots of lines of complex code
var n = l.get(0); // Err, what is n?
Not Everything Can Be Inferred
int[] firstSixPrimes = {2, 3, 5, 7, 11, 13};
var firstSixPrimes = {2, 3, 5, 7, 11, 13};
error: cannot infer type for local variable firstSixPrimes
var firstSixPrimes = {2, 3, 5, 7, 11, 13};
^
(array initializer needs an explicit target-type)
var firstSixPrimes = new int[]{2, 3, 5, 7, 11, 13};
var firstTwoPrimes = new Integer[]{2, 3};
Types Required On Both Sides
var list = null;
error: cannot infer type for local variable list
var list = null;
^
(variable initializer is 'null')
Types Required On Both Sides
var list;
list = new ArrayList<String>();
error: cannot infer type for local variable list
var list;
^
(cannot use 'var' on variable without initializer)
No Multiple Variable Declaration
62
var a, b = 1;
error: 'var' is not allowed in a compound declaration
Literals with var (Good)
• Original
‒ boolean ready = true;
‒ char ch = 'x';
‒ long sum = 0L;
‒ String label = "Foo";
Literals with var (Good)
• With var
‒ var ready = true;
‒ var ch = 'x';
‒ var sum = 0L;
‒ var label = "Foo";
Literals with var (Dangerous)
• Original
‒ byte flags = 0;
‒ short mask = 0x7fff;
‒ long base = 10;
Literals with var (Dangerous)
• Original
‒ var flags = 0;
‒ var mask = 0x7fff;
‒ var base = 10;
All these cases will infer int
Beware of Multiple Type Inference
var itemQueue = new PriorityQueue<>();
Diamond operator,
primary type
inference
Secondary type
inference
itemQueue infered as PriorityQueue<Object>();
PriorityQueue<Integer> itemQueue = new PriorityQueue<>();
Programming To An Interface
• Common to use interface rather than concrete type
• Using var always infers concrete type
• Polymorphism still works
‒ArrayList<String> is still a List
‒You can use myList wherever a List is required
List<String> myList = new ArrayList<>();
var myList = new ArrayList<String>();
Lambdas and var
Predicate<String> blankLine = s -> s.isBlank();
var blankLine = s -> s.isBlank();
error: cannot infer type for local variable blankLine
var blankLine = s -> s.isBlank();
^
(lambda expression needs an explicit target-type)
Intersection Types
<T extends Closeable & Iterable<E>> T getData() {
// Return something that implements both
// Closeable and Iterable<E>
}
Valid Java syntax
Intersection Types
• The problem
<E> Optional<E> firstMatch(Predicate<? super E> condition) {
XXX elements = getData();
try (elements) {
return StreamSupport.stream(elements.spliterator(), false)
.filter(condition)
.findAny();
}
}
elements must implement Closeable
elements must implement Iterable<E>
XXX is Closeable & Iterable<E>, which won't compile
Intersection Types
• The solution: var
<E> Optional<E> firstMatch(Predicate<? super E> condition) {
var elements = getData();
try (elements) {`
return StreamSupport.stream(elements.spliterator(), false)
.filter(condition)
.findAny();
}
}
Compiler infers a valid type that is impossible to express with Java syntax
Inner Classes
73
• This code won't compile
Object fruit = new Object() {
String name = "apple";
String inFrench() {
return "pomme";
}
};
System.out.println("Fruit = " + fruit.name);
System.out.println("In French = " + fruit.inFrench());
Inner Classes
74
• Using var this will compile and run
‒ The key is non-denotable types
var fruit = new Object() {
String name = "apple";
String inFrench() {
return "pomme";
}
};
System.out.println("Fruit = " + fruit.name);
System.out.println("In French = " + fruit.inFrench());
var: Reserved Type (Not Keyword)
var var = new Var();
public class var {
public var(String x) {
...
}
}
public class Var {
public Var(String x) {
...
}
}
Puzzler 1
static boolean calc1(int mask) {
long temp = 0x12345678;
return (((temp << 6) | temp) & mask) > 0;
}
Puzzler 1
• Should we use var? Yes? No?
static boolean calc1(int mask) {
var temp = 0x12345678;
return (((temp << 6) | temp) & mask) > 0;
}
Puzzler 1
• 0x12345678 fits in an int
‒ Using var will infer an int, not a long
• Passing a mask < 0 will give different results
‒ Using long, mask < 0 returns true
‒ Using var (infer int), mask < 0 returns false
Puzzler 2
static List<String> create1(boolean foo, boolean bar) {
List<String> list = new ArrayList<>();
if (foo)
list.add("foo");
if (bar)
list.add("bar");
return list;
}
Puzzler 2
• Should we use var? Yes? No?
static List<String> create1(boolean foo, boolean bar) {
var list = new ArrayList<>();
if (foo)
list.add("foo");
if (bar)
list.add("bar");
return list;
}
Puzzler 2
• Remember, "Beware of multiple type inference"
‒ var list = new ArrayList<>();
‒ Diamond operator infers Object
error: incompatible types: ArrayList<Object> cannot be
converted to List<String>
return list;
Puzzler 3
• Good use of var? Yes? No?
static List<Integer> listRemoval() {
List<Integer> list =
new ArrayList<>(Arrays.asList(1, 3, 5, 7, 9));
var v = valueToRemove();
list.remove(v);
return list;
}
// Separate class, package or module (in a galaxy far, far away)
static Integer valueToRemove() {
return 3;
}
Puzzler 3
• New intern arrives and changes code...
• Unexpected change in behaviour
static int valueToRemove() {
return 3;
}
List.remove(int) // Remove element at given index
List.remove(Object) // Remove first instance of object
{1,3,7,9} // Using var with changed valueToRemove
{1,5,7,9} // Using var with unchanged valueToRemove
Guidelines For Use of var
84
1. Reading code is more important that writing it
2. Code should be clear from local reasoning
3. Code readability shouldn't depend on an IDE
4. Choose variable names that provide useful information
5. Minimise the scope of local variables
6. Consider var when the initialiser provides sufficient information
7. Use var to break up chained or nested expressions
8. Take care when using var with generics
9. Take care when using var with literals
JDK 11
JDK 11: Extend Local-Variable Syntax
• Lambda parameters
list.stream()
.map(s -> s.toLowerCase())
.collect(Collectors.toList());
list.stream()
.map((var s) -> s.toLowerCase())
.collect(Collectors.toList());
list.stream()
.map((@Notnull var s) -> s.toLowerCase())
.collect(Collectors.toList());
New APIs
87
• New I/O methods
 InputStream nullInputStream()
 OutputStream nullOutputStream()
 Reader nullReader()
 Writer nullWriter()
• Optional
 isEmpty() // Opposite of isPresent
New APIs
88
• New String methods
‒ isBlank()
‒ Stream lines()
‒ String repeat(int)
‒ String strip()
‒ String stripLeading()
‒ String stripTrailing()
New APIs
89
• Predicate not(Predicate)
lines.stream()
.filter(s -> !s.isBlank())
lines.stream()
.filter(Predicate.not(String::isBlank))
lines.stream()
.filter(not(String::isBlank))
Missing Modules
90
• Remember, "Clean applications that only use java.se..."
• The java.se.ee aggregator module removed in JDK 11
• Affected modules
‒ java.corba
‒ java.transaction
‒ java.activation
‒ java.xml.bind
‒ java.xml.ws
‒ java.xml.ws.annotation
Resolving Missing Modules
91
• All modules (except CORBA) have standalone versions
‒ Maven central
‒ Relevant JSR RI
• Deploy standalone version on the upgrade module path
‒ --upgrade-module-path <path>
• Deploy standalone version on the classpath
JDK 12
Switch Expressions (Preview)
93
• 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
Old-Style Switch Statement
94
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); };
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);
};
New Old-Style Switch Expression
outside:
for (day : dayList)
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:
continue outside;
};
Illegal jump through switch
expression
Streams
• New collector, teeing
‒ teeing(Collector, Collector, BiFunction)
• Collect a stream using two collectors
• Use a BiFunction to merge the two collections
98
Collector 1
Collector 2
BiFunction
Stream Result
Streams
99
// Averaging
Double average = Stream.of(1, 4, 5, 2, 1, 7)
.collect(teeing(summingDouble(i -> i), counting(),
(sum, n) -> sum / n));
JDK 13
Text Blocks (Preview)
String webPage = """
<html>
<body>
<p>My web page</p>
</body>
</html>""";
System.out.println(webPage);
$ java WebPage
<html>
<body>
<p>My web page</p>
</body>
</html>
$
incidental white space
Text Blocks (Preview)
String webPage = """
<html>
<body>
<p>My web page</p>
</body>
</html>
""";
System.out.println(webPage);
$ java WebPage
<html>
<body>
<p>My web page</p>
</body>
</html>
$
Additional blank line
incidental white space
Intentional indentation
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
106
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;
}
}
Records (Preview)
107
record Point(double x, double y) { }
record Range(int low, int high) {
public Range { // Compact constructor
if (low > high)
throw new IllegalArgumentException("Bad values");
}
}
Record Additional Details
108
• 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 java.lang.Record
‒ 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
Using instanceof
109
if (obj instanceof String) {
String s = (String)obj;
System.out.println(s.length());
}
Pattern Matching instanceof (Preview)
110
if (obj instanceof String s)
System.out.println(s.length());
else
// Use of s not allowed here
if (obj instanceof String s && s.length() > 0)
System.out.println(s.length());
// Compiler error
if (obj instanceof String s || s.length() > 0)
System.out.println(s.length());
Pattern Matching instanceof (Preview)
111
if (!(o instanceof String s && s.length() > 3)
return;
System.out.println(s.length());
Pattern Matching instanceof
112
• Be careful of scope!
class BadPattern {
String s = "One";
void testMyObject(Object o) {
if (o instanceof String s) {
System.out.println(s); // Prints contents of o
s = s + " Two"; // Modifies pattern variable
}
System.out.println(s); // Prints "One"
}
}
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
114
• Who's never had an NullPointerException?
• Enabled with -XX:+ShowCodeDetailsInExceptionMessages
a.b.c.i = 99;
Exception in thread "main" java.lang.NullPointerException
at Prog.main(Prog.java:5)
Exception in thread "main" java.lang.NullPointerException:
Cannot read field "c" because "a.b" is null
at Prog.main(Prog.java:5)
JDK 15
Java Inheritance
116
• A class (or interface) in Java can be sub-classed by any class
‒ Unless it is marked as final
Shape
Triangle Square Pentagon
Sealed Classes (JEP 360)
117
• 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
Sealed Classes (JEP 360)
118
• 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
Triangle Square Pentagon Circle
X
Sealed Classes (JEP 360)
119
• 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 { ... }
Contextual Keyword Humour
120
int non = 2;
int sealed = 1;
var var = non-sealed;
Hidden Classes (JEP 371)
121
• 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
Records (Second Preview)
122
• 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
Records (Second Preview)
123
• Local records
‒ Like a local class
‒ Implicitly static
List<Seller> findTopSellers(List<Seller> sellers, int month) {
// Local record
record Sales(Seller seller, double sales) {}
return sellers.stream()
.map(seller -> new Sales(seller, salesInMonth(seller, month)))
.sorted((s1, s2) -> Double.compare(s2.sales(), s1.sales()))
.map(Sales::seller)
.collect(toList());
}
Records (Second Preview)
124
• 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 { ... }
JDK 16
Pattern Matching instanceof (JEP 394)
126
• 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 (x instanceof Object o) …
 It will always succeed and so is pointless
Records (JEP 395)
127
• Records now final, i.e., part of the Java SE specification
• Record fields are (really) final
‒ Cannot be changed via reflection (will throw IllegalAccessException)
• Native methods explicitly prohibited
‒ Could introduce behaviour dependent on external state
• Inner classes can now declare explicit/implicit static members
‒ Allows an inner class to declare a member that is a Record class
Add UNIX-Domain Socket Channels
128
• 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 = UnixDomainSocketAddress.of("/tmp/foo");
Streams mapMulti
129
• 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
• 1 to (0..1) example
Stream.of("Java", "Python", "JavaScript", "C#", "Ruby")
.mapMulti((str, consumer) -> {
if (str.length() > 4)
consumer.accept(str.length()); // lengths larger than 4
})
.forEach(i -> System.out.print(i + " "));
// 6 10
Stream mapMulti
130
• 1 to 1 example
Stream.of("Java", "Python", "JavaScript", "C#", "Ruby")
.mapMulti((str, consumer) -> consumer.accept(str.length()))
.forEach(i -> System.out.print(i + " "));
// 4 6 10 2 4
Stream mapMulti
131
• 1 to many example
Stream.of("Java", "Python", "JavaScript", "C#", "Ruby", "")
.mapMulti((str, consumer) -> {
for (int i = 0; i < str.length(); i++)
consumer.accept(str.length());
})
.forEach(i -> System.out.print(i + " "));
// 4 4 4 4 6 6 6 6 6 6 10 10 10 10 10 10 10 10 10 10 2 2 4 4 4 4
Vector API (JEP 338)
132
• 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
Vector API (JEP 338)
133
void scalarComputation(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; 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 < a.length; i += SPECIES.length()) {
var m = SPECIES.indexInRange(i, a.length);
var va = FloatVector.fromArray(SPECIES, a, i, m);
var vb = FloatVector.fromArray(SPECIES, b, i, m);
var vc = va.mul(va).
add(vb.mul(vb)).
neg();
vc.intoArray(c, i, m);
}
}
Foreign-Memory Access API (JEP 393)
134
• 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 = MemorySegment.allocateNative(100)) {
for (int i = 0; i < 25; i++)
MemoryAccess.setIntAtOffset(segment, i * 4, i);
}
Foreign-Memory Access API (JEP 393)
135
• Example using MemoryLayout and VarHandle
‒ Simpler access of structured data
SequenceLayout intArrayLayout
= MemoryLayout.ofSequence(25,
MemoryLayout.ofValueBits(32,
ByteOrder.nativeOrder()));
VarHandle indexedElementHandle
= intArrayLayout.varHandle(int.class,
PathElement.sequenceElement());
try (MemorySegment segment = MemorySegment.allocateNative(intArrayLayout)) {
for (int i = 0; i < intArrayLayout.elementCount().getAsLong(); i++)
indexedElementHandle.set(segment, (long) i, i);
}
Foreign Linker API (JEP 389): Incubator
136
• 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 = CLinker.getInstance();
var lookup = LibraryLookup.ofDefault();
// get a native method handle for 'getpid' function
var getpid = linker.downcallHandle(lookup.lookup("getpid").get(),
MethodType.methodType(int.class),
FunctionDescriptor.of(CLinker.C_INT));
System.out.println((int)getpid.invokeExact());
}
Warnings for Value-Based Classes
137
• 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
Summary
Zulu Enterprise
139
• Enhanced build of OpenJDK source code
 Fully TCK tested
 JDK 6, 7, 8, 11 and 13
 TLS1.3, Flight Recorder backports for Zulu 8
• 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
Zulu Extended Support
140
• Backporting of bug fixes and security patches from supported OpenJDK
release
• Zulu 8 supported until December 2030
• LTS releases have 9 years active + 2 years passive support
• JDK 15 is a Medium Term Support release
‒ Bridge to next LTS release (JDK 17)
‒ Supported until 18 months after JDK 17 release
Conclusions
141
• The six-month release cycle is working well
• Not all releases will have lots of new features
• Use Zulu builds of OpenJDK if you want to deploy to production
• Java continues to evolve!
THANK YOU

More Related Content

What's hot (20)

PDF
Native Java with GraalVM
Sylvain Wallez
 
PPTX
1 java programming- introduction
jyoti_lakhani
 
PDF
JVM JIT-compiler overview @ JavaOne Moscow 2013
Vladimir Ivanov
 
PDF
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Edureka!
 
PPT
TypeScript Presentation
Patrick John Pacaña
 
PPTX
Android jetpack compose | Declarative UI
Ajinkya Saswade
 
PDF
Java 10 New Features
Ali BAKAN
 
PPTX
55 New Features in Java SE 8
Simon Ritter
 
PPTX
Java virtual machine
Nikhil Sharma
 
PDF
Spring boot introduction
Rasheed Waraich
 
PPTX
Introduction to java
Sandeep Rawat
 
PPTX
Introduction to java
Saba Ameer
 
PDF
Introduction to basics of java
vinay arora
 
PPTX
Gradle
Jadson Santos
 
KEY
JavaOne 2012 - JVM JIT for Dummies
Charles Nutter
 
PDF
Gradle Introduction
Dmitry Buzdin
 
PPTX
Java seminar
devendrakhairwa
 
PPTX
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
Lucas Jellema
 
PPTX
What's new in Java 11
Michel Schudel
 
PPTX
core java
Roushan Sinha
 
Native Java with GraalVM
Sylvain Wallez
 
1 java programming- introduction
jyoti_lakhani
 
JVM JIT-compiler overview @ JavaOne Moscow 2013
Vladimir Ivanov
 
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Edureka!
 
TypeScript Presentation
Patrick John Pacaña
 
Android jetpack compose | Declarative UI
Ajinkya Saswade
 
Java 10 New Features
Ali BAKAN
 
55 New Features in Java SE 8
Simon Ritter
 
Java virtual machine
Nikhil Sharma
 
Spring boot introduction
Rasheed Waraich
 
Introduction to java
Sandeep Rawat
 
Introduction to java
Saba Ameer
 
Introduction to basics of java
vinay arora
 
JavaOne 2012 - JVM JIT for Dummies
Charles Nutter
 
Gradle Introduction
Dmitry Buzdin
 
Java seminar
devendrakhairwa
 
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
Lucas Jellema
 
What's new in Java 11
Michel Schudel
 
core java
Roushan Sinha
 

Similar to Modern Java Workshop (20)

PDF
Java SE 9 modules (JPMS) - an introduction
Stephen Colebourne
 
PDF
Java SE 9 modules - an introduction (July 2018)
Stephen Colebourne
 
PPTX
JDK 9 and JDK 10 Deep Dive
Simon Ritter
 
PPTX
Java 9: Deep Dive into Modularity and Dealing with Migration Issues
GlobalLogic Ukraine
 
PDF
Java 9, JShell, and Modularity
Mohammad Hossein Rimaz
 
PPTX
Java Platform Module System
Vignesh Ramesh
 
PPTX
Java 9 Module System Introduction
Dan Stine
 
PPTX
Preparing for java 9 modules upload
Ryan Cuprak
 
PDF
Java 9 preview
Ivan Krylov
 
PPTX
JDK 9: Big Changes To Make Java Smaller
Simon Ritter
 
PPTX
JDK 9 Deep Dive
Simon Ritter
 
PPT
Java 9 Module System
Hasan Ünal
 
PDF
What we can expect from Java 9 by Ivan Krylov
J On The Beach
 
PPTX
Advanced modular development
Srinivasan Raghavan
 
PPTX
What's New in Java 9
Richard Langlois P. Eng.
 
PDF
Haj 4344-java se 9 and the application server-1
Kevin Sutter
 
PDF
A Journey through the JDKs (Java 9 to Java 11)
Markus Günther
 
PPTX
Java modulesystem
Marc Kassis
 
PDF
JavaOne 2016: Life after Modularity
DanHeidinga
 
Java SE 9 modules (JPMS) - an introduction
Stephen Colebourne
 
Java SE 9 modules - an introduction (July 2018)
Stephen Colebourne
 
JDK 9 and JDK 10 Deep Dive
Simon Ritter
 
Java 9: Deep Dive into Modularity and Dealing with Migration Issues
GlobalLogic Ukraine
 
Java 9, JShell, and Modularity
Mohammad Hossein Rimaz
 
Java Platform Module System
Vignesh Ramesh
 
Java 9 Module System Introduction
Dan Stine
 
Preparing for java 9 modules upload
Ryan Cuprak
 
Java 9 preview
Ivan Krylov
 
JDK 9: Big Changes To Make Java Smaller
Simon Ritter
 
JDK 9 Deep Dive
Simon Ritter
 
Java 9 Module System
Hasan Ünal
 
What we can expect from Java 9 by Ivan Krylov
J On The Beach
 
Advanced modular development
Srinivasan Raghavan
 
What's New in Java 9
Richard Langlois P. Eng.
 
Haj 4344-java se 9 and the application server-1
Kevin Sutter
 
A Journey through the JDKs (Java 9 to Java 11)
Markus Günther
 
Java modulesystem
Marc Kassis
 
JavaOne 2016: Life after Modularity
DanHeidinga
 
Ad

More from Simon Ritter (20)

PPTX
Java Pattern Puzzles Java Pattern Puzzles
Simon Ritter
 
PPTX
Keeping Your Java Hot by Solving the JVM Warmup Problem
Simon Ritter
 
PPTX
Cloud Native Compiler
Simon Ritter
 
PPTX
Java On CRaC
Simon Ritter
 
PPTX
The Art of Java Type Patterns
Simon Ritter
 
PPTX
Modern Java Workshop
Simon Ritter
 
PPTX
Java performance monitoring
Simon Ritter
 
PPTX
Getting the Most From Modern Java
Simon Ritter
 
PPTX
Building a Better JVM
Simon Ritter
 
PPTX
JDK 14 Lots of New Features
Simon Ritter
 
PPTX
Java after 8
Simon Ritter
 
PPTX
How to Choose a JDK
Simon Ritter
 
PPTX
Java Programming
Simon Ritter
 
PPTX
The Latest in Enterprise JavaBeans Technology
Simon Ritter
 
PPTX
Developing Enterprise Applications Using Java Technology
Simon Ritter
 
PPTX
Is Java Still Free?
Simon Ritter
 
PPTX
Moving Towards JDK 12
Simon Ritter
 
PPTX
JDK 9, 10, 11 and Beyond
Simon Ritter
 
PPTX
Java Is Still Free
Simon Ritter
 
PPTX
JDK 9, 10, 11 and Beyond
Simon Ritter
 
Java Pattern Puzzles Java Pattern Puzzles
Simon Ritter
 
Keeping Your Java Hot by Solving the JVM Warmup Problem
Simon Ritter
 
Cloud Native Compiler
Simon Ritter
 
Java On CRaC
Simon Ritter
 
The Art of Java Type Patterns
Simon Ritter
 
Modern Java Workshop
Simon Ritter
 
Java performance monitoring
Simon Ritter
 
Getting the Most From Modern Java
Simon Ritter
 
Building a Better JVM
Simon Ritter
 
JDK 14 Lots of New Features
Simon Ritter
 
Java after 8
Simon Ritter
 
How to Choose a JDK
Simon Ritter
 
Java Programming
Simon Ritter
 
The Latest in Enterprise JavaBeans Technology
Simon Ritter
 
Developing Enterprise Applications Using Java Technology
Simon Ritter
 
Is Java Still Free?
Simon Ritter
 
Moving Towards JDK 12
Simon Ritter
 
JDK 9, 10, 11 and Beyond
Simon Ritter
 
Java Is Still Free
Simon Ritter
 
JDK 9, 10, 11 and Beyond
Simon Ritter
 
Ad

Recently uploaded (20)

PPTX
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PPTX
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
PDF
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
PDF
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
PPTX
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PDF
Online Queue Management System for Public Service Offices in Nepal [Focused i...
Rishab Acharya
 
PDF
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PPTX
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
PDF
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
PDF
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
PDF
Alexander Marshalov - How to use AI Assistants with your Monitoring system Q2...
VictoriaMetrics
 
PDF
Unlock Efficiency with Insurance Policy Administration Systems
Insurance Tech Services
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
Online Queue Management System for Public Service Offices in Nepal [Focused i...
Rishab Acharya
 
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
Alexander Marshalov - How to use AI Assistants with your Monitoring system Q2...
VictoriaMetrics
 
Unlock Efficiency with Insurance Policy Administration Systems
Insurance Tech Services
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 

Modern Java Workshop

  • 1. From JDK 9 to 16 New Java Workshop Presented by Simon Ritter, Deputy CTO | Azul Systems Inc.
  • 2. Introduction 2 •Six-month release cadence •Seven releases since JDK 9 •More features being delivered faster than ever before Java has changed… …a lot
  • 3. Incubator Modules 3 • 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)
  • 4. Preview Features 4 • 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)
  • 7. Why Do We Need Modularity in Java? 7 • JDK 1.0 ‒ 122 library classes for simplifying application development • JDK 8.0 ‒ Over 4,500 public classes in the rt.jar file • JDK 9 ‒ 27 Java SE modules, 48 JDK modules • Two sides to modularity: 1. JDK core libraries 2. Application code
  • 8. Module Fundamentals 8 • Module is a grouping of code ‒ For Java this is a collection of packages • Modules can contain other things ‒ Native code ‒ Resources ‒ Configuration data com.azul.zoop com.azul.zoop.alpha.Name com.azul.zoop.alpha.Position com.azul.zoop.beta.Animal com.azul.zoop.beta.Reptile com.azul.zoop.theta.Zoo com.azul.zoop.theta.Lake
  • 9. Module Declaration module com.azul.zoop {} module-info.java com/azul/zoop/alpha/Name.java com/azul/zoop/alpha/Position.java com/azul/zoop/beta/Animal.java com/azul/zoop/beta/Reptile.java com/azul/zoop/theta/Zoo.java com/azul/zoop/theta/Lake.java
  • 10. Module Dependencies module com.azul.zoop { requires com.azul.zeta; } com.azul.zoop com.azul.zeta
  • 11. Module Dependencies module com.azul.zapp { requires com.azul.zoop; requires java.sql; } com.azul.zapp com.azul.zoop java.sql
  • 13. Module Dependency Graph 13 • No missing dependencies • No cyclic dependencies • No split packages
  • 14. Readability v. Dependency com.azul.zapp java.sql java.logging module java.sql { requires transitive java.logging; } Driver d = … Logger l = d.getParentLogger(); l.log(“azul’); Implied readability
  • 15. Module Implied Readability Graph com.azul.zapp java.base java.sql com.azul.zoop com.azul.zeta java.xml java.logging explicit implicit implied
  • 16. Package Visibility module com.azul.zoop { requires com.azul.zeta; exports com.azul.zoop.alpha; exports com.azul.zoop.beta to com.azul.zapp; } com.azul.zoop com.azul.zoop.alpha com.azul.zoop.beta com.azul.zoop.theta com.azul.zapp only
  • 17. More Package Visibility open module com.azul.zoop { requires com.azul.zeta; } com.azul.zoop com.azul.zoop.alpha com.azul.zoop.beta com.azul.zoop.theta com.azul.zoop.alpha com.azul.zoop.beta com.azul.zoop.theta REFLECTION IMPORT
  • 18. Even More Package Visibility module com.azul.zoop { requires com.azul.zeta; exports com.azul.zoop.alpha; exports com.azul.zoop.beta to com.azul.zapp; opens com.azul.theta; } com.azul.zoop com.azul.zoop.theta REFLECTION IMPORT com.azul.zoop.alpha com.azul.zoop.beta com.azul.zapp only
  • 19. Restricted Keywords module requires requires; exports exports to to; module { opens opens; }
  • 20. Accessibility • For a package to be visible ‒ The package must be exported by the containing module ‒ The containing module must be read by the using module • Public types from those packages can then be used com.azul.zoop com.azul.zapp reads
  • 22. Module Path $ javac –modulepath dir1:dir2:dir3
  • 23. Compilation With Module Path $ javac –-module-path mods –d mods src/module-info.java src/com/azul/zoop/alpha/Name.java mods/module-info.class mods/com/azul/zoop/alpha/Name.class src/module-info.java src/com/azul/zoop/alpha/Name.java
  • 24. Application Execution • -p is the abbreviation of --module-path $ java –p mods –m com.azul.zapp/com.azul.zapp.Main Azul application initialised! module name main class
  • 25. Packaging With Modular JAR Files mods/module-info.class mods/com/azul/zapp/Main.class $ jar --create --file=mylib/zapp.jar --main-class=com.azul.zapp.Main -C mods . module-info.class com/azul/zapp/Main.class zapp.jar
  • 26. Application Execution (JAR) $ java –p mylib:mods –m com.azul.zapp Azul application initialised!
  • 27. Linking Modular run-time image … conf bin jlink $ jlink --module-path $JDKMODS --add-modules java.base –-output myimage $ myimage/bin/java –-list-modules [email protected]
  • 28. Linking An Application $ jlink --module-path $JDKMODS:$MYMODS --add-modules com.azul.zapp –-output myimage $ myimage/bin/java –-list-modules java.base@9 java.logging@9 java.sql@9 java.xml@9 [email protected] [email protected] [email protected]
  • 29. The Implications Of jlink • "Write once, run anywhere"  Long term Java slogan, mainly held true • jlink generated runtime may not include all Java SE modules ‒ But is still a conforming Java implementation ‒ To conform to the specification, the runtime:  Must include the java.base module  If other modules are included, all transitive module dependencies must also be included  Defined as a closed implementation
  • 31. Typical Application (JDK 8) jar jar jar JDK jar jar jar jar jar jar jar jar jar Classpath
  • 32. Typical Application (JDK 9) jar jar jar module java.base module java.desktop module java.datatransfer module java.xml jar jar jar jar jar jar jar jar jar Unnamed module
  • 34. Run Application With Classpath $ java –classpath lib/myapp.jar: lib/mylib.jar: lib/libgl.jar: lib/gluegen.jar: lib/jogl.jar: myapp.Main
  • 36. Application module-info.java module myapp { requires mylib; requires java.base; requires java.sql; requires libgl; ???? requires gluegen; ???? requires jogl; ???? }
  • 38. Automatic Modules 38 • Real modules • Simply place unmodified jar file on module path ‒ Rather than classpath • No changes to JAR file • Module name derived from JAR file name • Exports all its packages ‒ No selectivity • Automatically requires all modules on the module path
  • 40. Run Application With Modules $ java –classpath lib/myapp.jar: lib/mylib.jar: lib/libgl.jar: lib/gluegen.jar: lib/jogl.jar: myapp.Main $ java –p mylib:lib –m myapp
  • 41. Migrating Applications To The Java Platform Module System
  • 42. Migration Guidance From Oracle "Clean applications that just depend on java.se should just work"
  • 43. Migrating Applications to JPMS 43 • Initially, leave everything on the classpath • Anything on the classpath is in the unnamed module ‒ All packages are exported ‒ The unnamed module depends on all modules • Migrate to modules as required ‒ Try automatic modules ‒ Move existing jar files from classpath to modulepath
  • 44. Classpath v Modulepath classpath modulepath Unnamed module jar jar jar module-info.class jar module-info.class jar Automatic module module-info.class
  • 45. Reversing Encapsulation • "The Big Kill Switch" --illegal-access • Four options: ‒ permit (current default) ‒ warn ‒ debug ‒ deny (JDK 16 default)
  • 46. Reversing Encapsulation • Big kill switch overrides encapsulation ‒ From the unnamed module (i.e. classpath) ‒ Allows unlimited refective access to named modules  Not from named modules • Warning messages written to error stream • Useful to understand use of --add-exports and --add-opens when migrating to named modules
  • 47. Reversing Encapsulation 47 • Allowing direct access to encapsulated APIs ‒ --add-exports • Allowing reflective access to encapsulated APIs ‒ --add-opens --add-exports java.management/com.sun.jmx.remote.internal=mytest --add-exports java.management/sun.management=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED
  • 48. Finding Dependencies: jdeps > jdeps --module-path /opt/javafx-sdk-11/lib --add-modules=javafx.controls --list-deps FlightTracker.jar JDK removed internal API/com.sun.media.jfxmediaimpl.platform.ios java.base java.datatransfer java.desktop/java.awt.dnd.peer java.desktop/sun.awt java.desktop/sun.awt.dnd java.desktop/sun.swing java.logging java.scripting java.sql java.xml jdk.jsobject jdk.unsupported jdk.unsupported.desktop jdk.xml.dom
  • 50. Java Storage Basics 50 • Fields (instance and static) ‒ Part of an object, exist for the lifetime of an object ‒ Initialisation guaranteed by compiler • Local variables ‒ Scoped to region of code (method, statement, block) ‒ Initialisation not guaranteed ‒ Cheap when allocated on the stack ‒ Name and use is often more important than the type
  • 51. Local Variable Type Inference • Why? ‒ JavaScript has it so it must be good ‒ Streams hide intermediate types ‒ Why not expand this elsewhere? ‒ var can make code more concise  Without sacrificing readability List l = names.stream() // Stream<String> .filter(s -> s.length() > 0) // Stream<String> .map(s -> getRecord(s)) // Stream<Record> .collect(toList()); // ArrayList<Record>
  • 52. Simple Uses of Local Variables ArrayList<String> nameList = new ArrayList<String>(); List<String> userList = new ArrayList<>(); Stream<String> stream = userList.stream(); for (String name : userList) { ... } for (int i = 0; i < 10; i++) { ... }
  • 53. Simple Uses of Local Variable Type Inference var userList = new ArrayList<String>(); // Infers ArrayList<String> var stream = userList.stream(); // Infers Stream<String> for (var name : userList) { // Infers String ... } for (var i = 0; i < 10; i++) { // Infers int ... }
  • 54. Simple Uses of var • Clearer try-with-resources try (InputStream inputStream = socket.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, UTF_8); BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) { // Use bufferedReader }
  • 55. Simple Uses of var • Clearer try-with-resources try (var inputStream = socket.getInputStream(); var inputStreamReader = new inputStreamReader(inputStream, UTF_8); var bufferedReader = new BufferedReader(inputStreamReader)) { // Use bufferedReader }
  • 56. More Typing With Less Typing • Java is still statically typed var name = "Simon"; // Infers String, so name is String name = "Dylan"; // Still String name = 42; // Not a String error: incompatible types: int cannot be converted to String
  • 57. Final and Non-Final 57 • var simply indicates the compiler infers the type • Use of var does not make a variable final • Still need final • No shortcut for final var (like val) ‒ How often do you make local-variables final? var name = "Simon"; name = "Dylan"; // name is not final final var name = "Simon";
  • 58. Action At A Distance var l = new ArrayList<String>(); var s = l.stream(); // Lots of lines of complex code var n = l.get(0); // Err, what is n?
  • 59. Not Everything Can Be Inferred int[] firstSixPrimes = {2, 3, 5, 7, 11, 13}; var firstSixPrimes = {2, 3, 5, 7, 11, 13}; error: cannot infer type for local variable firstSixPrimes var firstSixPrimes = {2, 3, 5, 7, 11, 13}; ^ (array initializer needs an explicit target-type) var firstSixPrimes = new int[]{2, 3, 5, 7, 11, 13}; var firstTwoPrimes = new Integer[]{2, 3};
  • 60. Types Required On Both Sides var list = null; error: cannot infer type for local variable list var list = null; ^ (variable initializer is 'null')
  • 61. Types Required On Both Sides var list; list = new ArrayList<String>(); error: cannot infer type for local variable list var list; ^ (cannot use 'var' on variable without initializer)
  • 62. No Multiple Variable Declaration 62 var a, b = 1; error: 'var' is not allowed in a compound declaration
  • 63. Literals with var (Good) • Original ‒ boolean ready = true; ‒ char ch = 'x'; ‒ long sum = 0L; ‒ String label = "Foo";
  • 64. Literals with var (Good) • With var ‒ var ready = true; ‒ var ch = 'x'; ‒ var sum = 0L; ‒ var label = "Foo";
  • 65. Literals with var (Dangerous) • Original ‒ byte flags = 0; ‒ short mask = 0x7fff; ‒ long base = 10;
  • 66. Literals with var (Dangerous) • Original ‒ var flags = 0; ‒ var mask = 0x7fff; ‒ var base = 10; All these cases will infer int
  • 67. Beware of Multiple Type Inference var itemQueue = new PriorityQueue<>(); Diamond operator, primary type inference Secondary type inference itemQueue infered as PriorityQueue<Object>(); PriorityQueue<Integer> itemQueue = new PriorityQueue<>();
  • 68. Programming To An Interface • Common to use interface rather than concrete type • Using var always infers concrete type • Polymorphism still works ‒ArrayList<String> is still a List ‒You can use myList wherever a List is required List<String> myList = new ArrayList<>(); var myList = new ArrayList<String>();
  • 69. Lambdas and var Predicate<String> blankLine = s -> s.isBlank(); var blankLine = s -> s.isBlank(); error: cannot infer type for local variable blankLine var blankLine = s -> s.isBlank(); ^ (lambda expression needs an explicit target-type)
  • 70. Intersection Types <T extends Closeable & Iterable<E>> T getData() { // Return something that implements both // Closeable and Iterable<E> } Valid Java syntax
  • 71. Intersection Types • The problem <E> Optional<E> firstMatch(Predicate<? super E> condition) { XXX elements = getData(); try (elements) { return StreamSupport.stream(elements.spliterator(), false) .filter(condition) .findAny(); } } elements must implement Closeable elements must implement Iterable<E> XXX is Closeable & Iterable<E>, which won't compile
  • 72. Intersection Types • The solution: var <E> Optional<E> firstMatch(Predicate<? super E> condition) { var elements = getData(); try (elements) {` return StreamSupport.stream(elements.spliterator(), false) .filter(condition) .findAny(); } } Compiler infers a valid type that is impossible to express with Java syntax
  • 73. Inner Classes 73 • This code won't compile Object fruit = new Object() { String name = "apple"; String inFrench() { return "pomme"; } }; System.out.println("Fruit = " + fruit.name); System.out.println("In French = " + fruit.inFrench());
  • 74. Inner Classes 74 • Using var this will compile and run ‒ The key is non-denotable types var fruit = new Object() { String name = "apple"; String inFrench() { return "pomme"; } }; System.out.println("Fruit = " + fruit.name); System.out.println("In French = " + fruit.inFrench());
  • 75. var: Reserved Type (Not Keyword) var var = new Var(); public class var { public var(String x) { ... } } public class Var { public Var(String x) { ... } }
  • 76. Puzzler 1 static boolean calc1(int mask) { long temp = 0x12345678; return (((temp << 6) | temp) & mask) > 0; }
  • 77. Puzzler 1 • Should we use var? Yes? No? static boolean calc1(int mask) { var temp = 0x12345678; return (((temp << 6) | temp) & mask) > 0; }
  • 78. Puzzler 1 • 0x12345678 fits in an int ‒ Using var will infer an int, not a long • Passing a mask < 0 will give different results ‒ Using long, mask < 0 returns true ‒ Using var (infer int), mask < 0 returns false
  • 79. Puzzler 2 static List<String> create1(boolean foo, boolean bar) { List<String> list = new ArrayList<>(); if (foo) list.add("foo"); if (bar) list.add("bar"); return list; }
  • 80. Puzzler 2 • Should we use var? Yes? No? static List<String> create1(boolean foo, boolean bar) { var list = new ArrayList<>(); if (foo) list.add("foo"); if (bar) list.add("bar"); return list; }
  • 81. Puzzler 2 • Remember, "Beware of multiple type inference" ‒ var list = new ArrayList<>(); ‒ Diamond operator infers Object error: incompatible types: ArrayList<Object> cannot be converted to List<String> return list;
  • 82. Puzzler 3 • Good use of var? Yes? No? static List<Integer> listRemoval() { List<Integer> list = new ArrayList<>(Arrays.asList(1, 3, 5, 7, 9)); var v = valueToRemove(); list.remove(v); return list; } // Separate class, package or module (in a galaxy far, far away) static Integer valueToRemove() { return 3; }
  • 83. Puzzler 3 • New intern arrives and changes code... • Unexpected change in behaviour static int valueToRemove() { return 3; } List.remove(int) // Remove element at given index List.remove(Object) // Remove first instance of object {1,3,7,9} // Using var with changed valueToRemove {1,5,7,9} // Using var with unchanged valueToRemove
  • 84. Guidelines For Use of var 84 1. Reading code is more important that writing it 2. Code should be clear from local reasoning 3. Code readability shouldn't depend on an IDE 4. Choose variable names that provide useful information 5. Minimise the scope of local variables 6. Consider var when the initialiser provides sufficient information 7. Use var to break up chained or nested expressions 8. Take care when using var with generics 9. Take care when using var with literals
  • 86. JDK 11: Extend Local-Variable Syntax • Lambda parameters list.stream() .map(s -> s.toLowerCase()) .collect(Collectors.toList()); list.stream() .map((var s) -> s.toLowerCase()) .collect(Collectors.toList()); list.stream() .map((@Notnull var s) -> s.toLowerCase()) .collect(Collectors.toList());
  • 87. New APIs 87 • New I/O methods  InputStream nullInputStream()  OutputStream nullOutputStream()  Reader nullReader()  Writer nullWriter() • Optional  isEmpty() // Opposite of isPresent
  • 88. New APIs 88 • New String methods ‒ isBlank() ‒ Stream lines() ‒ String repeat(int) ‒ String strip() ‒ String stripLeading() ‒ String stripTrailing()
  • 89. New APIs 89 • Predicate not(Predicate) lines.stream() .filter(s -> !s.isBlank()) lines.stream() .filter(Predicate.not(String::isBlank)) lines.stream() .filter(not(String::isBlank))
  • 90. Missing Modules 90 • Remember, "Clean applications that only use java.se..." • The java.se.ee aggregator module removed in JDK 11 • Affected modules ‒ java.corba ‒ java.transaction ‒ java.activation ‒ java.xml.bind ‒ java.xml.ws ‒ java.xml.ws.annotation
  • 91. Resolving Missing Modules 91 • All modules (except CORBA) have standalone versions ‒ Maven central ‒ Relevant JSR RI • Deploy standalone version on the upgrade module path ‒ --upgrade-module-path <path> • Deploy standalone version on the classpath
  • 93. Switch Expressions (Preview) 93 • 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
  • 94. Old-Style Switch Statement 94 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); };
  • 95. 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); };
  • 96. 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); };
  • 97. New Old-Style Switch Expression outside: for (day : dayList) 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: continue outside; }; Illegal jump through switch expression
  • 98. Streams • New collector, teeing ‒ teeing(Collector, Collector, BiFunction) • Collect a stream using two collectors • Use a BiFunction to merge the two collections 98 Collector 1 Collector 2 BiFunction Stream Result
  • 99. Streams 99 // Averaging Double average = Stream.of(1, 4, 5, 2, 1, 7) .collect(teeing(summingDouble(i -> i), counting(), (sum, n) -> sum / n));
  • 100. JDK 13
  • 101. Text Blocks (Preview) String webPage = """ <html> <body> <p>My web page</p> </body> </html>"""; System.out.println(webPage); $ java WebPage <html> <body> <p>My web page</p> </body> </html> $ incidental white space
  • 102. Text Blocks (Preview) String webPage = """ <html> <body> <p>My web page</p> </body> </html> """; System.out.println(webPage); $ java WebPage <html> <body> <p>My web page</p> </body> </html> $ Additional blank line incidental white space Intentional indentation
  • 103. 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); };
  • 104. 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); };
  • 105. JDK 14
  • 106. Simple Java Data Class 106 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; } }
  • 107. Records (Preview) 107 record Point(double x, double y) { } record Range(int low, int high) { public Range { // Compact constructor if (low > high) throw new IllegalArgumentException("Bad values"); } }
  • 108. Record Additional Details 108 • 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 java.lang.Record ‒ 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
  • 109. Using instanceof 109 if (obj instanceof String) { String s = (String)obj; System.out.println(s.length()); }
  • 110. Pattern Matching instanceof (Preview) 110 if (obj instanceof String s) System.out.println(s.length()); else // Use of s not allowed here if (obj instanceof String s && s.length() > 0) System.out.println(s.length()); // Compiler error if (obj instanceof String s || s.length() > 0) System.out.println(s.length());
  • 111. Pattern Matching instanceof (Preview) 111 if (!(o instanceof String s && s.length() > 3) return; System.out.println(s.length());
  • 112. Pattern Matching instanceof 112 • Be careful of scope! class BadPattern { String s = "One"; void testMyObject(Object o) { if (o instanceof String s) { System.out.println(s); // Prints contents of o s = s + " Two"; // Modifies pattern variable } System.out.println(s); // Prints "One" } }
  • 113. 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""";
  • 114. Helpful NullPointerException 114 • Who's never had an NullPointerException? • Enabled with -XX:+ShowCodeDetailsInExceptionMessages a.b.c.i = 99; Exception in thread "main" java.lang.NullPointerException at Prog.main(Prog.java:5) Exception in thread "main" java.lang.NullPointerException: Cannot read field "c" because "a.b" is null at Prog.main(Prog.java:5)
  • 115. JDK 15
  • 116. Java Inheritance 116 • A class (or interface) in Java can be sub-classed by any class ‒ Unless it is marked as final Shape Triangle Square Pentagon
  • 117. Sealed Classes (JEP 360) 117 • 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
  • 118. Sealed Classes (JEP 360) 118 • 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 Triangle Square Pentagon Circle X
  • 119. Sealed Classes (JEP 360) 119 • 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 { ... }
  • 120. Contextual Keyword Humour 120 int non = 2; int sealed = 1; var var = non-sealed;
  • 121. Hidden Classes (JEP 371) 121 • 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
  • 122. Records (Second Preview) 122 • 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
  • 123. Records (Second Preview) 123 • Local records ‒ Like a local class ‒ Implicitly static List<Seller> findTopSellers(List<Seller> sellers, int month) { // Local record record Sales(Seller seller, double sales) {} return sellers.stream() .map(seller -> new Sales(seller, salesInMonth(seller, month))) .sorted((s1, s2) -> Double.compare(s2.sales(), s1.sales())) .map(Sales::seller) .collect(toList()); }
  • 124. Records (Second Preview) 124 • 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 { ... }
  • 125. JDK 16
  • 126. Pattern Matching instanceof (JEP 394) 126 • 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 (x instanceof Object o) …  It will always succeed and so is pointless
  • 127. Records (JEP 395) 127 • Records now final, i.e., part of the Java SE specification • Record fields are (really) final ‒ Cannot be changed via reflection (will throw IllegalAccessException) • Native methods explicitly prohibited ‒ Could introduce behaviour dependent on external state • Inner classes can now declare explicit/implicit static members ‒ Allows an inner class to declare a member that is a Record class
  • 128. Add UNIX-Domain Socket Channels 128 • 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 = UnixDomainSocketAddress.of("/tmp/foo");
  • 129. Streams mapMulti 129 • 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 • 1 to (0..1) example Stream.of("Java", "Python", "JavaScript", "C#", "Ruby") .mapMulti((str, consumer) -> { if (str.length() > 4) consumer.accept(str.length()); // lengths larger than 4 }) .forEach(i -> System.out.print(i + " ")); // 6 10
  • 130. Stream mapMulti 130 • 1 to 1 example Stream.of("Java", "Python", "JavaScript", "C#", "Ruby") .mapMulti((str, consumer) -> consumer.accept(str.length())) .forEach(i -> System.out.print(i + " ")); // 4 6 10 2 4
  • 131. Stream mapMulti 131 • 1 to many example Stream.of("Java", "Python", "JavaScript", "C#", "Ruby", "") .mapMulti((str, consumer) -> { for (int i = 0; i < str.length(); i++) consumer.accept(str.length()); }) .forEach(i -> System.out.print(i + " ")); // 4 4 4 4 6 6 6 6 6 6 10 10 10 10 10 10 10 10 10 10 2 2 4 4 4 4
  • 132. Vector API (JEP 338) 132 • 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
  • 133. Vector API (JEP 338) 133 void scalarComputation(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; 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 < a.length; i += SPECIES.length()) { var m = SPECIES.indexInRange(i, a.length); var va = FloatVector.fromArray(SPECIES, a, i, m); var vb = FloatVector.fromArray(SPECIES, b, i, m); var vc = va.mul(va). add(vb.mul(vb)). neg(); vc.intoArray(c, i, m); } }
  • 134. Foreign-Memory Access API (JEP 393) 134 • 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 = MemorySegment.allocateNative(100)) { for (int i = 0; i < 25; i++) MemoryAccess.setIntAtOffset(segment, i * 4, i); }
  • 135. Foreign-Memory Access API (JEP 393) 135 • Example using MemoryLayout and VarHandle ‒ Simpler access of structured data SequenceLayout intArrayLayout = MemoryLayout.ofSequence(25, MemoryLayout.ofValueBits(32, ByteOrder.nativeOrder())); VarHandle indexedElementHandle = intArrayLayout.varHandle(int.class, PathElement.sequenceElement()); try (MemorySegment segment = MemorySegment.allocateNative(intArrayLayout)) { for (int i = 0; i < intArrayLayout.elementCount().getAsLong(); i++) indexedElementHandle.set(segment, (long) i, i); }
  • 136. Foreign Linker API (JEP 389): Incubator 136 • 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 = CLinker.getInstance(); var lookup = LibraryLookup.ofDefault(); // get a native method handle for 'getpid' function var getpid = linker.downcallHandle(lookup.lookup("getpid").get(), MethodType.methodType(int.class), FunctionDescriptor.of(CLinker.C_INT)); System.out.println((int)getpid.invokeExact()); }
  • 137. Warnings for Value-Based Classes 137 • 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
  • 139. Zulu Enterprise 139 • Enhanced build of OpenJDK source code  Fully TCK tested  JDK 6, 7, 8, 11 and 13  TLS1.3, Flight Recorder backports for Zulu 8 • 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
  • 140. Zulu Extended Support 140 • Backporting of bug fixes and security patches from supported OpenJDK release • Zulu 8 supported until December 2030 • LTS releases have 9 years active + 2 years passive support • JDK 15 is a Medium Term Support release ‒ Bridge to next LTS release (JDK 17) ‒ Supported until 18 months after JDK 17 release
  • 141. Conclusions 141 • The six-month release cycle is working well • Not all releases will have lots of new features • Use Zulu builds of OpenJDK if you want to deploy to production • Java continues to evolve!