SlideShare a Scribd company logo
1 of 142
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

What's hot (20)

Advanced Reflection in Java
Advanced Reflection in JavaAdvanced Reflection in Java
Advanced Reflection in Java
 
Gradle - the Enterprise Automation Tool
Gradle  - the Enterprise Automation ToolGradle  - the Enterprise Automation Tool
Gradle - the Enterprise Automation Tool
 
Graal in GraalVM - A New JIT Compiler
Graal in GraalVM - A New JIT CompilerGraal in GraalVM - A New JIT Compiler
Graal in GraalVM - A New JIT Compiler
 
55 New Features in Java SE 8
55 New Features in Java SE 855 New Features in Java SE 8
55 New Features in Java SE 8
 
Tiered Compilation in Hotspot JVM
Tiered Compilation in Hotspot JVMTiered Compilation in Hotspot JVM
Tiered Compilation in Hotspot JVM
 
GraalVm and Quarkus
GraalVm and QuarkusGraalVm and Quarkus
GraalVm and Quarkus
 
GraalVM
GraalVMGraalVM
GraalVM
 
Gradle
GradleGradle
Gradle
 
Understanding Java Garbage Collection
Understanding Java Garbage CollectionUnderstanding Java Garbage Collection
Understanding Java Garbage Collection
 
Understanding Monorepos
Understanding MonoreposUnderstanding Monorepos
Understanding Monorepos
 
Java 9/10/11 - What's new and why you should upgrade
Java 9/10/11 - What's new and why you should upgradeJava 9/10/11 - What's new and why you should upgrade
Java 9/10/11 - What's new and why you should upgrade
 
JVM++: The Graal VM
JVM++: The Graal VMJVM++: The Graal VM
JVM++: The Graal VM
 
Introduction to GraalVM
Introduction to GraalVMIntroduction to GraalVM
Introduction to GraalVM
 
An Introduction to Gradle for Java Developers
An Introduction to Gradle for Java DevelopersAn Introduction to Gradle for Java Developers
An Introduction to Gradle for Java Developers
 
Secrets of Performance Tuning Java on Kubernetes
Secrets of Performance Tuning Java on KubernetesSecrets of Performance Tuning Java on Kubernetes
Secrets of Performance Tuning Java on Kubernetes
 
Write your Helm charts as a professional. Design templates and inheritance. B...
Write your Helm charts as a professional. Design templates and inheritance. B...Write your Helm charts as a professional. Design templates and inheritance. B...
Write your Helm charts as a professional. Design templates and inheritance. B...
 
Quarkus入門
Quarkus入門Quarkus入門
Quarkus入門
 
GraalVMを3つの主機能から眺めてみよう(Oracle Groundbreakers APAC Virtual Tour 2020 講演資料)
GraalVMを3つの主機能から眺めてみよう(Oracle Groundbreakers APAC Virtual Tour 2020 講演資料)GraalVMを3つの主機能から眺めてみよう(Oracle Groundbreakers APAC Virtual Tour 2020 講演資料)
GraalVMを3つの主機能から眺めてみよう(Oracle Groundbreakers APAC Virtual Tour 2020 講演資料)
 
GitLab.pptx
GitLab.pptxGitLab.pptx
GitLab.pptx
 
Introduction to kubernetes
Introduction to kubernetesIntroduction to kubernetes
Introduction to kubernetes
 

Similar to Modern Java Workshop

Similar to Modern Java Workshop (20)

Java9 and the impact on Maven Projects (JFall 2016)
Java9 and the impact on Maven Projects (JFall 2016)Java9 and the impact on Maven Projects (JFall 2016)
Java9 and the impact on Maven Projects (JFall 2016)
 
Java 9 and the impact on Maven Projects (JavaOne 2016)
Java 9 and the impact on Maven Projects (JavaOne 2016)Java 9 and the impact on Maven Projects (JavaOne 2016)
Java 9 and the impact on Maven Projects (JavaOne 2016)
 
What we can expect from Java 9 by Ivan Krylov
What we can expect from Java 9 by Ivan KrylovWhat we can expect from Java 9 by Ivan Krylov
What we can expect from Java 9 by Ivan Krylov
 
Preparing for java 9 modules upload
Preparing for java 9 modules uploadPreparing for java 9 modules upload
Preparing for java 9 modules upload
 
Java 9 preview
Java 9 previewJava 9 preview
Java 9 preview
 
JDK 9: Big Changes To Make Java Smaller
JDK 9: Big Changes To Make Java SmallerJDK 9: Big Changes To Make Java Smaller
JDK 9: Big Changes To Make Java Smaller
 
Java 9: Deep Dive into Modularity and Dealing with Migration Issues
Java 9: Deep Dive into Modularity and Dealing with Migration IssuesJava 9: Deep Dive into Modularity and Dealing with Migration Issues
Java 9: Deep Dive into Modularity and Dealing with Migration Issues
 
Apache Maven supports all Java (JokerConf 2018)
Apache Maven supports all Java (JokerConf 2018)Apache Maven supports all Java (JokerConf 2018)
Apache Maven supports all Java (JokerConf 2018)
 
Java Platform Module System
Java Platform Module SystemJava Platform Module System
Java Platform Module System
 
JDK 9 Deep Dive
JDK 9 Deep DiveJDK 9 Deep Dive
JDK 9 Deep Dive
 
JDK 9: Big Changes To Make Java Smaller
JDK 9: Big Changes To Make Java SmallerJDK 9: Big Changes To Make Java Smaller
JDK 9: Big Changes To Make Java Smaller
 
Project Jigsaw in JDK9
Project Jigsaw in JDK9Project Jigsaw in JDK9
Project Jigsaw in JDK9
 
JDK 9 and JDK 10 Deep Dive
JDK 9 and JDK 10 Deep DiveJDK 9 and JDK 10 Deep Dive
JDK 9 and JDK 10 Deep Dive
 
Java 9 / Jigsaw - AJUG/VJUG session
Java 9 / Jigsaw - AJUG/VJUG  sessionJava 9 / Jigsaw - AJUG/VJUG  session
Java 9 / Jigsaw - AJUG/VJUG session
 
Migrating to Java 9 Modules
Migrating to Java 9 ModulesMigrating to Java 9 Modules
Migrating to Java 9 Modules
 
JavaOne 2016: Life after Modularity
JavaOne 2016: Life after ModularityJavaOne 2016: Life after Modularity
JavaOne 2016: Life after Modularity
 
Voxxed Days Thessaloniki 2016 - JDK 9 : Big Changes To Make Java Smaller
Voxxed Days Thessaloniki 2016 - JDK 9 : Big Changes To Make Java Smaller Voxxed Days Thessaloniki 2016 - JDK 9 : Big Changes To Make Java Smaller
Voxxed Days Thessaloniki 2016 - JDK 9 : Big Changes To Make Java Smaller
 
Voxxed Days Thessaloniki 2016 - Keynote - JDK 9 : Big Changes To Make Java Sm...
Voxxed Days Thessaloniki 2016 - Keynote - JDK 9 : Big Changes To Make Java Sm...Voxxed Days Thessaloniki 2016 - Keynote - JDK 9 : Big Changes To Make Java Sm...
Voxxed Days Thessaloniki 2016 - Keynote - JDK 9 : Big Changes To Make Java Sm...
 
Java modules
Java modulesJava modules
Java modules
 
Java 9 and the impact on Maven Projects (ApacheCon Europe 2016)
Java 9 and the impact on Maven Projects (ApacheCon Europe 2016)Java 9 and the impact on Maven Projects (ApacheCon Europe 2016)
Java 9 and the impact on Maven Projects (ApacheCon Europe 2016)
 

More from Simon Ritter

More from Simon Ritter (20)

Cloud Native Compiler
Cloud Native CompilerCloud Native Compiler
Cloud Native Compiler
 
Java On CRaC
Java On CRaCJava On CRaC
Java On CRaC
 
The Art of Java Type Patterns
The Art of Java Type PatternsThe Art of Java Type Patterns
The Art of Java Type Patterns
 
Modern Java Workshop
Modern Java WorkshopModern Java Workshop
Modern Java Workshop
 
Java performance monitoring
Java performance monitoringJava performance monitoring
Java performance monitoring
 
Getting the Most From Modern Java
Getting the Most From Modern JavaGetting the Most From Modern Java
Getting the Most From Modern Java
 
Building a Better JVM
Building a Better JVMBuilding a Better JVM
Building a Better JVM
 
JDK 14 Lots of New Features
JDK 14 Lots of New FeaturesJDK 14 Lots of New Features
JDK 14 Lots of New Features
 
Java after 8
Java after 8Java after 8
Java after 8
 
How to Choose a JDK
How to Choose a JDKHow to Choose a JDK
How to Choose a JDK
 
Java Programming
Java ProgrammingJava Programming
Java Programming
 
The Latest in Enterprise JavaBeans Technology
The Latest in Enterprise JavaBeans TechnologyThe Latest in Enterprise JavaBeans Technology
The Latest in Enterprise JavaBeans Technology
 
Developing Enterprise Applications Using Java Technology
Developing Enterprise Applications Using Java TechnologyDeveloping Enterprise Applications Using Java Technology
Developing Enterprise Applications Using Java Technology
 
Is Java Still Free?
Is Java Still Free?Is Java Still Free?
Is Java Still Free?
 
Moving Towards JDK 12
Moving Towards JDK 12Moving Towards JDK 12
Moving Towards JDK 12
 
JDK 9, 10, 11 and Beyond
JDK 9, 10, 11 and BeyondJDK 9, 10, 11 and Beyond
JDK 9, 10, 11 and Beyond
 
Java Is Still Free
Java Is Still FreeJava Is Still Free
Java Is Still Free
 
JDK 9, 10, 11 and Beyond
JDK 9, 10, 11 and BeyondJDK 9, 10, 11 and Beyond
JDK 9, 10, 11 and Beyond
 
Java Support: What's changing
Java Support:  What's changingJava Support:  What's changing
Java Support: What's changing
 
JDK 9: The Start of a New Future for Java
JDK 9: The Start of a New Future for JavaJDK 9: The Start of a New Future for Java
JDK 9: The Start of a New Future for Java
 

Recently uploaded

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...
Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...
Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 

Recently uploaded (20)

WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
WSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - Kanchana
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...
Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...
Abortion Pill Prices Boksburg [(+27832195400*)] 🏥 Women's Abortion Clinic in ...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 

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 java.base@9.0
  • 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 com.azul.zapp@1.0 com.azul.zoop@1.0 com.azul.zeta@1.0
  • 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!