SlideShare a Scribd company logo
1 of 360
Download to read offline
Yann-Gaël Guéhéneuc
(/jan/, he/il)
Work licensed under Creative Commons
BY-NC-SA 4.0 International
New Java
yann-gael.gueheneuc@concordia.ca
Version 0.22.1
2024/03/28
2/360
Patrick Naughton
Scott McNealy
Mike Sheridan James Gosling
1991
3/360
4/360
Naming
 Java
– 1995/05/23
– Language
 JDK (Java Development Kit)
– Compiler (Java Language Specification)
– VM (Java Virtual Machine Specification)
– APIs/Libraries (Java Class Libraries)
5/360
Process
 JCP: Java Community Process
– Established in 1998
– JSR-387 describes JCP v2.11
6/360
Documents
 JLSs: Java Language Specifications
– What is Java
 JSRs: Java Specification Requests
– Parts of the JCP
– New specifications and technologies
– JDK/OpenJDK
 JEPs: Java Enhancement Proposals
– Experimental ideas
– Could become JSRs
https://stackoverflow.com/questions/51282326/what-is-the-difference-or-relation-between-jls-jsr-and-jep
7/360
Disclaimer
8/360
Too
Many
Features
Disclaimer
No
Preview
No
Incubator
9/360
Organisation
 Per release
– With some cross-references
 Three categories
– Language
– JVM
– APIs
Misc
+
10/360
Java 5
Java 6
2004/09/30
2006/12/11
11/360
LANGUAGE (ONLY)
12/360
Enums
 Special data type
– Declares/defines
variables set to
constants
interface PseudoEnum0 {
int YES = 0;
int NO = 1;
}
interface Interface1 {
public boolean foo();
}
enum RealEnum1 implements Interface1 {
YES {
public boolean foo() {
return true;
}
},
NO {
public boolean foo() {
return false;
}
};
public boolean bar() {
return this.foo();
}
}
13/360
Enums
 Based on anonymous classes
System.out.println(RealEnum1.YES.bar());
System.out.println(RealEnum1.NO.bar());
System.out.print("Superclass: ");
System.out.println(RealEnum1.NO.getClass().getSuperclass());
System.out.print("Class: ");
System.out.println(RealEnum1.NO.getClass());
for (final Method method : RealEnum1.NO.getClass().getDeclaredMethods()) {
System.out.print("tMethods: ");
System.out.println(method);
}
14/360
Enums
 Based on anonymous classes
System.out.println(RealEnum1.YES.bar());
System.out.println(RealEnum1.NO.bar());
System.out.print("Superclass: ");
System.out.println(RealEnum1.NO.getClass().getSuperclass());
System.out.print("Class: ");
System.out.println(RealEnum1.NO.getClass());
for (final Method method : RealEnum1.NO.getClass().getDeclaredMethods()) {
System.out.print("tMethods: ");
System.out.println(method);
}
true
false
Superclass: class net.ptidej.newjava.enums.RealEnum1
Class: class net.ptidej.newjava.enums.RealEnum1$2
Methods: public boolean net.ptidej.newjava.enums.RealEnum1$2.foo()
15/360
Enums
Enum Simulated Enum
interface Interface1 {
public boolean foo();
}
enum RealEnum1 implements Interface1 {
YES {
public boolean foo() {
return true;
}
},
NO {
public boolean foo() {
return false;
}
};
public boolean bar() {
return this.foo();
}
}
interface Interface1 {
public boolean foo();
}
abstract class SimulatedEnum1 implements Interface1 {
public static final SimulatedEnum1 YES =
new SimulatedEnum1() {
@Override
public boolean foo() {
return true;
}
};
public static final SimulatedEnum1 NO =
new SimulatedEnum1() {
@Override
public boolean foo() {
return false;
}
};
private SimulatedEnum1() {
}
public boolean bar() {
return this.foo();
}
}
16/360
Enums
Enum Simulated Enum
interface Interface1 {
public boolean foo();
}
enum RealEnum1 implements Interface1 {
YES {
public boolean foo() {
return true;
}
},
NO {
public boolean foo() {
return false;
}
};
public boolean bar() {
return this.foo();
}
}
interface Interface1 {
public boolean foo();
}
abstract class SimulatedEnum1 implements Interface1 {
public static final SimulatedEnum1 YES =
new SimulatedEnum1() {
@Override
public boolean foo() {
return true;
}
};
public static final SimulatedEnum1 NO =
new SimulatedEnum1() {
@Override
public boolean foo() {
return false;
}
};
private SimulatedEnum1() {
}
public boolean bar() {
return this.foo();
}
}
Instances of two
anonymous classes
17/360
Enums
Enum Simulated Enum
interface Interface1 {
public boolean foo();
}
enum RealEnum1 implements Interface1 {
YES {
public boolean foo() {
return true;
}
},
NO {
public boolean foo() {
return false;
}
};
public boolean bar() {
return this.foo();
}
}
Why private?
interface Interface1 {
public boolean foo();
}
abstract class SimulatedEnum1 implements Interface1 {
public static final SimulatedEnum1 YES =
new SimulatedEnum1() {
@Override
public boolean foo() {
return true;
}
};
public static final SimulatedEnum1 NO =
new SimulatedEnum1() {
@Override
public boolean foo() {
return false;
}
};
private SimulatedEnum1() {
}
public boolean bar() {
return this.foo();
}
}
Instances of two
anonymous classes
18/360
Enums
 More than just syntactic sugar
– Constants are constant expressions
final RealEnum3 v = // ...
switch (v) {
case YES:
System.out.println("YES");
break;
case NO:
System.out.println("NO");
break;
default:
throw // ...
}
final SimulatedEnum3 v1 = // ...
switch (v1) {
case SimulatedEnum3.YES:
System.out.println("YES");
break;
case SimulatedEnum3.NO:
System.out.println("NO");
break;
default:
throw // ...
}
19/360
Enums
 More than just syntactic sugar
– Constants are constant expressions
final RealEnum3 v = // ...
switch (v) {
case YES:
System.out.println("YES");
break;
case NO:
System.out.println("NO");
break;
default:
throw // ...
}
final SimulatedEnum3 v1 = // ...
switch (v1) {
case SimulatedEnum3.YES:
System.out.println("YES");
break;
case SimulatedEnum3.NO:
System.out.println("NO");
break;
default:
throw // ...
}
case expressions must be constant expressions
20/360
Enums
 No work around the compilation error
– Some constants are not constant expressions
final SimulatedEnum3 v1 = // ...
switch (v1) {
case SimulatedEnum3.YES:
System.out.println("YES");
break;
case SimulatedEnum3.NO:
System.out.println("NO");
break;
default:
throw // ...
}
final int v2 = // ...
switch (v2) {
case SimulatedEnum3.YES.constantID:
System.out.println("YES");
break;
case SimulatedEnum3.NO.constantID:
System.out.println("NO");
break;
default:
throw // ...
}
public final int constantID;
21/360
Java 7
2011/07/07
2011/07/07
22/360
LANGUAGE
23/360
Strings in switch
https://www.baeldung.com/java-switch
public String exampleOfSwitch(String animal) {
String result;
switch (animal) {
case "DOG" :
result = "domestic animal";
break;
case "CAT" :
result = "domestic animal";
break;
case "TIGER" :
result = "wild animal";
break;
default :
result = "unknown animal";
break;
}
return result;
}
24/360
try With Resources
 New interfaces
– java.lang.Closeable
– java.lang.AutoCloseable
https://www.baeldung.com/java-try-with-resources
try (final Scanner scanner = new Scanner(new File("test.txt"))) {
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
}
catch (final FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
25/360
Diamond Operator <>
https://www.baeldung.com/java-diamond-operator
List<String> cars = new ArrayList<String>();
List<String> cars = new ArrayList<>();
vs.
26/360
Vargs in Method Declaration
https://www.baeldung.com/java-varargs
https://www.baeldung.com/java-varargs
public String format() {
// ...
}
public String format(String value) {
//...
}
public String format(String val1, String val2) {
// ...
}
public String formatWithVarArgs(String... values) {
System.out.println(values[0]);
System.out.println(values[1]);
System.out.println(values[3]);
// ...
}
vs.
27/360
Binary Integer Literals
https://www.geeksforgeeks.org/java-program-to-illustrate-use-of-binary-literals/
// Byte type Binary Literal
byte a1 = 0b011;
// Short type Binary Literal
short b1 = 0b101;
// Int type Binary literal
int c1 = 0b011;
// Long type Binary literal
long d1 = 0b0000011111100011;
28/360
Underscores in Numeric Literals
int i = 12_34_56;
System.out.println(i);
https://www.geeksforgeeks.org/using-underscore-numeric-literals-java/
29/360
Multiple Exception Types
 Multiple exception types
 Multiple exceptions rethrown
with improved type checking
30/360
Multiple Exception Types
public static void main(final String[] args) {
try {
Example1.rethrow("abc");
}
catch (final FirstException | SecondException e) {
// Below assignment would throw a compile-time exception, e is implicitly final
// e = new Exception();
System.out.println(e.getMessage());
}
}
private static void rethrow(final String s) throws FirstException, SecondException {
try {
if (s.equals("First")) throw new FirstException("First");
else throw new SecondException("Second");
}
catch (final Exception e) {
// Below assignment would disable improved rethrow exception type checking
// e = new ThirdException();
throw e;
}
}
private static class FirstException extends Exception {
public FirstException(String msg) {
super(msg);
}
}
// ...
31/360
JVM
32/360
JSR-292: invokedynamic
 invokestatic, for class methods
 invokevirtual, for instance methods
 invokeinterface, for interface methods
 invokespecial, for instance initialisation,
superclass, and private methods
33/360
JSR-292: invokedynamic
Gilad Bracha, 2005
34/360
JSR-292: invokedynamic
 invokedynamic indicates that a dynamic
language run-time specific call occurs
 The call occurs through MethodHandle(s)
https://www.baeldung.com/java-method-handles
MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
MethodType mt = MethodType.methodType(String.class, char.class, char.class);
MethodHandle replaceMH = publicLookup.findVirtual(String.class, "replace", mt);
String output = (String) replaceMH.invoke("jovo", 'o', 'a');
35/360
APIS
36/360
JSR-166: Concurrency Utilities
 Concurrency utilities under JSR 166
 java.util.concurrent wants to be for
concurrency what java.util.Collections
is for collections
 With some JVM support
– Timing
– Atomics
– …
https://gee.cs.oswego.edu/dl/concurrency-interest/jsr166-slides.pdf
37/360
JSR-166: Concurrency Utilities
https://www.uml-diagrams.org/java-7-concurrent-uml-class-diagram-example.html
38/360
JSR-166: Concurrency Utilities
https://www.uml-diagrams.org/java-7-concurrent-uml-class-diagram-example.html
39/360
JSR-166: Concurrency Utilities
https://www.uml-diagrams.org/java-7-concurrent-uml-class-diagram-example.html
40/360
JSR-166: Concurrency Utilities
https://gee.cs.oswego.edu/dl/concurrency-interest/jsr166-slides.pdf
final Runnable runnable1 = new RunnableExample("executor.execute(...)");
final ExecutorService executor = Executors.newFixedThreadPool(10);
executor.execute(runnable1);
final Runnable runnable2 = new RunnableExample("new Thread(...)");
new Thread(runnable2).start();
vs.
41/360
JSR-166: Concurrency Utilities
class ImageRenderer {
Image render(final byte[] raw) {
return // ...
}
}
public class Example2 {
public void display(final byte[] raw) throws InterruptedException, ExecutionException {
final ExecutorService executor = Executors.newFixedThreadPool(10);
final ImageRenderer renderer = new ImageRenderer();
final Future<Image> image = executor.submit(new Callable<Image>() {
public Image call() {
return renderer.render(raw);
}
});
drawBorders(); // do other things ...
drawCaption(); // ... while executing
drawImage(image.get()); // use Future
}
// ...
https://gee.cs.oswego.edu/dl/concurrency-interest/jsr166-slides.pdf
42/360
JSR-166: Concurrency Utilities
public void run() {
synchronized (this.resource) {
this.resource.doSomething();
}
this.resource.doLogging();
}
public void run() {
try {
if (this. lock.tryLock(10, TimeUnit.SECONDS)) {
this.resource.doSomething();
}
}
catch (final InterruptedException exception) {
exception.printStackTrace();
}
finally {
this.lock.unlock();
}
this.resource.doLogging();
}
vs.
https://www.digitalocean.com/com
munity/tutorials/java-lock-example-
reentrantlock
43/360
JSR-166: Concurrency Utilities
https://www.geeksforgeeks.org/semaphore-in-java/
private final Semaphore semaphore;
private void connect(final String user)
throws InterruptedException {
System.out.println(getCurrentDateTime()
+ " : " + user + " waiting sem");
this.semaphore.acquire();
System.out.println(getCurrentDateTime()
+ " : " + user + " acquired sem");
Thread.sleep(1000); // Some work...
this.semaphore.release();
System.out.println(getCurrentDateTime()
+ " : " + user + " released sem");
}
https://mkyong.com/java/java-semaphore-examples/
44/360
JSR-166: Concurrency Utilities
https://www.geeksforgeeks.org/atomic-variables-in-java-with-examples/
class Counter extends Thread {
private final AtomicInteger count;
public Counter() {
this.count = new AtomicInteger();
}
public void run() {
final int max = 10_000_000;
for (int i = 0; i < max; i++) {
count.addAndGet(1);
}
}
public int getCount() {
return this.count.get();
}
}
45/360
JSR-203: New File I/O Library
 Extensive File I/O API
 Socket channel API
 Asynchronous I/O API
46/360
JSR-203: New File I/O Library
 Extensive File I/O API
https://www.baeldung.com/java-nio2-file-visitor
https://www.baeldung.com/java-nio2-file-visitor
public class Example1FileVisitor {
public static void main(final String[] args) throws IOException {
final Path startPath = Paths.get("D:DocumentsTutorials220926 - New Java");
final String fileName = "Example1FileVisitor.java";
final FileVisitorImpl visitor = new FileVisitorImpl(fileName, startPath);
Files.walkFileTree(startPath, visitor);
}
}
47/360
JSR-203: New File I/O Library
https://www.baeldung.com/java-nio2-file-visitor
class FileVisitorImpl implements FileVisitor<Path> {
private final String fileName;
private final Path startPath;
public FileVisitorImpl(final String aFileName, final Path aStartPath) {
this.fileName = aFileName;
this.startPath = aStartPath;
}
@Override
public FileVisitResult preVisitDirectory(final Path aPath, final BasicFileAttributes someAttributes) {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(final Path aPath, final BasicFileAttributes someAttributes) {
final String fileName = aPath.getFileName().toString();
if (fileName.equals(this.fileName)) {
return FileVisitResult.TERMINATE;
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(final Path aPath, final IOException anIOException) {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(final Path aPath, final IOException anIOException) {
try {
if (Files.isSameFile(aPath, this.startPath)) {
return FileVisitResult.TERMINATE;
}
} catch (final IOException e) {
e.printStackTrace();
}
return FileVisitResult.CONTINUE;
}
}
48/360
JSR-203: New File I/O Library
 Socket channel API – Client
public static void client() throws IOException {
final ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(9000));
final SocketChannel client = serverSocket.accept();
System.out.println("Connection set: " + client.getRemoteAddress());
final Path path = Paths.get("D:DocumentsTutorials220926 - New JavaReceivedFile.txt");
final FileChannel fileChannel = FileChannel.open(
path,
EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE));
final ByteBuffer buffer = ByteBuffer.allocate(1024);
while (client.read(buffer) > 0) {
buffer.flip();
fileChannel.write(buffer);
buffer.clear();
}
fileChannel.close();
System.out.println("File received");
client.close();
}
https://www.tutorialspoint.com/java_nio/java_nio_socket_channel.htm
49/360
JSR-203: New File I/O Library
 Socket channel API – Server
https://www.tutorialspoint.com/java_nio/java_nio_socket_channel.htm
public static void server() throws IOException {
final SocketChannel server = SocketChannel.open();
final SocketAddress socketAddr = new InetSocketAddress("localhost", 9000);
server.connect(socketAddr);
final Path path = Paths.get("D:DocumentsTutorials220926 - New JavaPatterns.txt");
final FileChannel fileChannel = FileChannel.open(path);
final ByteBuffer buffer = ByteBuffer.allocate(1024);
while (fileChannel.read(buffer) > 0) {
buffer.flip();
server.write(buffer);
buffer.clear();
}
fileChannel.close();
System.out.println("File sent");
server.close();
}
50/360
JSR-203: New File I/O Library
 Socket channel API – Main
public static void main(final String[] args) {
final Runnable runnableClient = new Runnable() {
public void run() {
try {
Example2SocketChannel.client();
} catch (final IOException e) {
}
}
};
final Runnable runnableServer = new Runnable() {
public void run() {
try {
Example2SocketChannel.server();
} catch (final IOException e) {
}
}
};
final ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(runnableClient);
executor.execute(runnableServer);
}
https://www.tutorialspoint.com/java_nio/java_nio_socket_channel.htm
51/360
JSR-203: New File I/O Library
 Asynchronous I/O API
“The asynchronous channel APIs were
introduced into the existing
java.nio.channels package […] by
prefixing […] with Asynchronous”
52/360
Translucent and Shaped Windows
 Improves Java Swing
 Allow new, nicer themes
https://ateraimemo.com/Swing/TranslucentFrame.html
Window.setShape(Shape s)
Window.setOpacity(float f)
53/360
Network Protocols
 Network protocols
– Stream Control
Transport Protocol
(SCTP)
– Sockets Direct
Protocol (SDP)
 In packages
– com.sun.nio.sctp
– com.sun.sdp
https://www.oracle.com/technical-resources/articles/javase/sctp.html
final SctpServerChannel ssc =
SctpServerChannel.open();
final InetSocketAddress serverAddr = // ...
ssc.bind(serverAddr);
while (true) {
final SctpChannel sc = ssc.accept();
final Date today = new Date();
cbuf.put(USformatter.format(today)).flip();
encoder.encode(cbuf, buf, true);
buf.flip();
messageInfo.streamNumber(FUS_STREAM);
sc.send(buf, messageInfo);
buf.clear();
cbuf.clear();
cbuf.put(FRformatter.format(today)).flip();
encoder.encode(cbuf, buf, true);
buf.flip();
messageInfo.streamNumber(FR_STREAM);
sc.send(buf, messageInfo);
buf.clear();
cbuf.clear();
// ...
54/360
Updates to XML and Unicode
 New system property named
org.jcp.xml.dsig.secureValidation
 New XML Processing Limits
 Regular Expression pattern matching
supports Unicode 6.0.0
– Major version of the Unicode Standard
55/360
Java 8
2014/03/18
56/360
LANGUAGE
57/360
default, static Interface Methods
public interface IA {
int foo();
default int bar() {
return 42;
}
}
public static void main(final String[] args) {
final IA anIA = new IA() {
public int foo() {
return 0;
}
};
System.out.println(anIA.foo());
System.out.println(anIA.bar());
final IA anotherIA = new IA() {
public int foo() {
return IA.super.bar();
}
public int bar() {
return 0;
}
};
System.out.println(anotherIA.foo());
System.out.println(anotherIA.bar());
}
58/360
default, static Interface Methods
public interface IA {
int foo();
default int bar() {
return 42;
}
}
public static void main(final String[] args) {
final IA anIA = new IA() {
public int foo() {
return 0;
}
};
System.out.println(anIA.foo());
System.out.println(anIA.bar());
final IA anotherIA = new IA() {
public int foo() {
return IA.super.bar();
}
public int bar() {
return 0;
}
};
System.out.println(anotherIA.foo());
System.out.println(anotherIA.bar());
}
0
42
42
0
59/360
default, static Interface Methods
 https://stackoverflow.c
om/questions/512877/
why-cant-i-define-a-
static-method-in-a-
java-interface
public interface IA {
int foo();
static int bar() {
return 42;
}
}
public class A {
int foo() {
return 0;
}
static int bar() {
return 42;
}
}
public static void main(final String[] args) {
final IA anIA = new IA() {
public int foo() {
return 0;
}
};
System.out.println(anIA.foo());
System.out.println(anIA.bar());
final A anA = new A();
System.out.println(anA.foo());
System.out.println(anA.bar());
}
60/360
default, static Interface Methods
 https://stackoverflow.c
om/questions/512877/
why-cant-i-define-a-
static-method-in-a-
java-interface
public interface IA {
int foo();
static int bar() {
return 42;
}
}
public class A {
int foo() {
return 0;
}
static int bar() {
return 42;
}
}
public static void main(final String[] args) {
final IA anIA = new IA() {
public int foo() {
return 0;
}
};
System.out.println(anIA.foo());
System.out.println(anIA.bar());
final A anA = new A();
System.out.println(anA.foo());
System.out.println(anA.bar());
}
61/360
default, static Interface Methods
 https://stackoverflow.c
om/questions/512877/
why-cant-i-define-a-
static-method-in-a-
java-interface
public interface IA {
int foo();
static int bar() {
return 42;
}
}
public class A {
int foo() {
return 0;
}
static int bar() {
return 42;
}
}
public static void main(final String[] args) {
final IA anIA = new IA() {
public int foo() {
return 0;
}
};
System.out.println(anIA.foo());
System.out.println(anIA.bar());
final A anA = new A();
System.out.println(anA.foo());
System.out.println(anA.bar());
}
System.out.println(IA.bar());
62/360
JSR-335, JEP-126: λ Expressions
 λ Expressions
interface Applicable<T, R> {
public R apply(final T aParameter);
}
public static void main(final String[] args) {
final Applicable<String, Integer> strlen = new Applicable<>() {
@Override
public Integer apply(final String aParameter) {
return aParameter.length();
}
};
System.out.println(strlen.apply("Hello, World!"));
}
https://jenkov.com/tutorials/java-functional-programming/functional-interfaces.html
63/360
JSR-335, JEP-126: λ Expressions



interface Applicable<T, R> {
public R apply(final T aParameter);
}
public static void main(final String[] args) {
final Applicable<String, Integer> strlen = new Applicable<>() {
@Override
public Integer apply(final String aParameter) {
return aParameter.length();
}
};
System.out.println(strlen.apply("Hello, World!"));
}
64/360
JSR-335, JEP-126: λ Expressions
 Lots of boilerplate code
 Difficult to understand
 Not common in the libraries
interface Applicable<T, R> {
public R apply(final T aParameter);
}
public static void main(final String[] args) {
final Applicable<String, Integer> strlen = new Applicable<>() {
@Override
public Integer apply(final String aParameter) {
return aParameter.length();
}
};
System.out.println(strlen.apply("Hello, World!"));
}
65/360
JSR-335, JEP-126: λ Expressions
 Solution
– Simple syntactic sugar
– Set of functional interfaces
– Libraries using these interfaces
66/360
JSR-335, JEP-126: λ Expressions
 Solution
– Simple syntactic sugar
– Set of functional interfaces
– Libraries using these interfaces
67/360
JSR-335, JEP-126: λ Expressions
 Solution
– Simple syntactic sugar
– Set of functional interfaces
– Libraries using these interfaces
interface Applicable<T, R> {
public R apply(final T aParameter);
}
public static void main(final String[] args) {
final Applicable<String, Integer> strlen = (paramter) -> paramter.length();
System.out.println(strlen.apply("Hello, World!"));
}
68/360
JSR-335, JEP-126: λ Expressions
 Solution
– Simple syntactic sugar
– Set of functional interfaces
– Libraries using these interfaces
interface Applicable<T, R> {
public R apply(final T aParameter);
}
public static void main(final String[] args) {
final Applicable<String, Integer> strlen = (paramter) -> paramter.length();
System.out.println(strlen.apply("Hello, World!"));
}
public static void main(final String[] args) {
final Applicable<String, Integer> strlen = String::length;
System.out.println(strlen.apply("Hello, World!"));
}
69/360
JSR-335, JEP-126: λ Expressions
 Solution
– Simple syntactic sugar
– Set of functional interfaces
– Libraries using these interfaces
http://blog.orfjackal.net/2014/07/java-8-functional-interface-naming-guide.html
70/360
JSR-335, JEP-126: λ Expressions
 Solution
– Simple syntactic sugar
– Set of functional interfaces
– Libraries using these interfaces
http://blog.orfjackal.net/2014/07/java-8-functional-interface-naming-guide.html
71/360
JSR-335, JEP-126: λ Expressions
 Solution
– Simple syntactic sugar
– Set of functional interfaces
– Libraries using these interfaces
https://blogs.oracle.com/javamagazine/post/functional-programming-in-java-part-1-lists-lambdas-and-method-references
72/360
JSR-335, JEP-126: λ Expressions
 Solution
– Simple syntactic sugar
– Set of functional interfaces
– Libraries using these interfaces
https://blogs.oracle.com/javamagazine/post/functional-programming-in-java-part-1-lists-lambdas-and-method-references
final List<String> friends = Arrays.asList("Rick Deckard", "Roy Batty", "Harry
Bryant", "Hannibal Chew", "Gaff", "Holden", "Leon Kowalski", "Taffey Lewis",
"Pris", "Rachael", "J.F. Sebastian", "Dr. Eldon Tyrell", "Zhora", "Hodge",
"Mary");
for (int i = 0; i < friends.size(); i++) {
System.out.println(friends.get(i));
}
for (String name : friends) {
System.out.println(name);
}
friends.forEach(new Consumer<String>() {
public void accept(final String aName) { System.out.println(aName); }});
friends.forEach((final String name) -> System.out.println(name));
friends.forEach((name) -> System.out.println(name));
friends.forEach(name -> System.out.println(name));
friends.forEach(System.out::println);
friends.stream().map(String::toUpperCase).forEach(
name -> System.out.print(name + " "));
System.out.println();
final List<String> namesStartingWithN = friends.stream().
filter(name -> name.startsWith("R")).collect(Collectors.toList());
System.out.println(namesStartingWithN);
73/360
JSR-335, JEP-126: λ Expressions
 But code duplication!
https://blogs.oracle.com/javamagazine/post/functional-programming-
in-java-part-2-lambda-reuse-lexical-scoping-and-closures-and-reduce
output = friends1.stream().filter(name -> name.startsWith("R")).collect(Collectors.toList());
System.out.println(output);
output = friends2.stream().filter(name -> name.startsWith("R")).collect(Collectors.toList());
System.out.println(output);
final Predicate<String> predicate = name -> name.startsWith("R");
output = friends1.stream().filter(predicate).collect(Collectors.toList());
System.out.println(output);
output = friends2.stream().filter(predicate).collect(Collectors.toList());
System.out.println(output);
vs.
74/360
JSR-335, JEP-126: λ Expressions
 But code duplication!
https://blogs.oracle.com/javamagazine/post/functional-programming-
in-java-part-2-lambda-reuse-lexical-scoping-and-closures-and-reduce
// Lexical scoping and closure
output = friends1.stream().filter(checkIfStartsWith("R")).collect(Collectors.toList());
System.out.println(output);
output = friends2.stream().filter(checkIfStartsWith("P")).collect(Collectors.toList());
System.out.println(output);
// Narrower lexical scoping
final Function<String, Predicate<String>> startsWithLetter = letter -> (name ->
name.startsWith(letter));
output = friends1.stream().filter(startsWithLetter.apply("R")).collect(Collectors.toList());
System.out.println(output);
output = friends2.stream().filter(startsWithLetter.apply("P")).collect(Collectors.toList());
System.out.println(output);
vs.
75/360
JSR-335, JEP-126: λ Expressions
 But code duplication!
https://blogs.oracle.com/javamagazine/post/functional-programming-
in-java-part-2-lambda-reuse-lexical-scoping-and-closures-and-reduce
// Lexical scoping and closure
output = friends1.stream().filter(checkIfStartsWith("R")).collect(Collectors.toList());
System.out.println(output);
output = friends2.stream().filter(checkIfStartsWith("P")).collect(Collectors.toList());
System.out.println(output);
// Narrower lexical scoping
final Function<String, Predicate<String>> startsWithLetter = letter -> (name ->
name.startsWith(letter));
output = friends1.stream().filter(startsWithLetter("R")).collect(Collectors.toList());
System.out.println(output);
output = friends2.stream().filter(startsWithLetter("P")).collect(Collectors.toList());
System.out.println(output);
vs.
76/360
JSR-335, JEP-126: λ Expressions
 But code duplication!
https://forum.devtalk.com/t/functional-programming-in-java-second-
edition-p-35-refactoring-to-narrow-the-scope-code/105447
// Lexical scoping and closure
output = friends1.stream().filter(checkIfStartsWith("R")).collect(Collectors.toList());
System.out.println(output);
output = friends2.stream().filter(checkIfStartsWith("P")).collect(Collectors.toList());
System.out.println(output);
// Narrower lexical scoping
final Function<String, Predicate<String>> startsWithLetter = letter -> (name ->
name.startsWith(letter));
output = friends1.stream().filter(startsWithLetter("R")).collect(Collectors.toList());
System.out.println(output);
output = friends2.stream().filter(startsWithLetter("P")).collect(Collectors.toList());
System.out.println(output);
vs.
77/360
JSR-308, JEP-104: Type Annotations
 Allow pluggable type systems
 Help enforce stronger typing
public class Example1 {
public static void main(final String[] args) {
final String aString = null;
final String anotherString = aString;
System.out.println(anotherString);
}
}
78/360
JSR-308, JEP-104: Type Annotations
 Allow pluggable type systems
 Help enforce stronger typing
public class Example1 {
public static void main(final String[] args) {
final String aString = null;
final String anotherString = aString;
System.out.println(anotherString);
}
}
public class Example1 {
public static void main(final String[] args) {
final String aString = null;
final @NonNull String anotherString = aString;
System.out.println(anotherString);
}
}
79/360
JSR-308, JEP-104: Type Annotations
 Allow pluggable type systems
 Help enforce stronger typing
public class Example1 {
public static void main(final String[] args) {
final String aString = null;
final String anotherString = aString;
System.out.println(anotherString);
}
}
public class Example1 {
public static void main(final String[] args) {
final String aString = null;
final @NonNull String anotherString = aString;
System.out.println(anotherString);
}
}
Null type mismatch: required
'@NonNull String' but the
provided value is null
80/360
JSR-308, JEP-104: Type Annotations
 Allow pluggable type systems
 Help enforce stronger typing
public class Example1 {
public static void main(final String[] args) {
final String aString = null;
final String anotherString = aString;
System.out.println(anotherString);
}
}
public class Example1 {
public static void main(final String[] args) {
final String aString = null;
final @NonNull String anotherString = aString;
System.out.println(anotherString);
}
}
public class Example1 {
public static void main(final String[] args) {
final String aString = "";
final @NonNull String anotherString = aString;
System.out.println(anotherString);
}
}
Null type mismatch: required
'@NonNull String' but the
provided value is null
81/360
JSR-308, JEP-104: Type Annotations
class A {
String getString() {
return null;
}
}
public class Example2 {
public static void foo1() {
final A a = new A();
final String aString = a.getString();
final @NonNull String anotherString = aString;
System.out.println(anotherString);
}
public static void foo2() {
final A a = new A();
final String aString = a.getString();
if (aString != null) {
final @NonNull String anotherString = aString;
System.out.println(anotherString);
}
}
}
82/360
JSR-308, JEP-104: Type Annotations
class A {
String getString() {
return null;
}
}
public class Example2 {
public static void foo1() {
final A a = new A();
final String aString = a.getString();
final @NonNull String anotherString = aString;
System.out.println(anotherString);
}
public static void foo2() {
final A a = new A();
final String aString = a.getString();
if (aString != null) {
final @NonNull String anotherString = aString;
System.out.println(anotherString);
}
}
}
Null type safety […] needs
unchecked conversion to
conform to '@NonNull String'
83/360
JSR-308, JEP-104: Type Annotations
 “The Checker Framework includes compiler
plug-ins ("checkers") that find bugs or verify
their absence. It also permits you to write
your own compiler plug-ins.”
– https://checkerframework.org/tutorial/
84/360
Unsigned Integer Arithmetic
 Comparison
 Division/Modulo
 Parsing
 Formatting
https://www.baeldung.com/java-unsigned-arithmetic
public class Example1 {
public static void main(String[] args) {
final int positive = Integer.MAX_VALUE;
final int negative = Integer.MIN_VALUE;
final int signedComparison = Integer.compare(positive, negative);
if (signedComparison > 0) {
System.out.println("Positive > negative (signed comparison)");
}
final int unsignedComparison = Integer.compareUnsigned(positive, negative);
if (unsignedComparison < 0) {
System.out.println("Positive NOT > negative (unsigned comparison)");
}
}
}
85/360
JEP-120: Repeating Annotations
 “Annotations, a form of metadata, provide
data about a program that is not part of the
program [and] have no direct effect on the
operation of the code they annotate.”
https://docs.oracle.com/javase/tutorial/java/annotations/
86/360
JEP-120: Repeating Annotations
 “Annotations, a form of metadata, provide
data about a program that is not part of the
program [and] have no direct effect on the
operation of the code they annotate.”
https://docs.oracle.com/javase/tutorial/java/annotations/
87/360
JEP-120: Repeating Annotations
https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99
@Retention(RetentionPolicy.RUNTIME)
@interface ScheduleNonRepeatable1 {
String dayOfMonth() default "First";
String dayOfWeek() default "Mon";
int hour() default 12;
}
@ScheduleNonRepeatable1(dayOfWeek = "Fri", hour = 23)
public class Example1 {
public static void main(final String[] args) {
final Example1 example1 = new Example1();
final Annotation annotation = example1.getClass().
getAnnotation(ScheduleNonRepeatable1.class);
System.out.println(annotation);
}
}
88/360
JEP-120: Repeating Annotations
https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99
@Retention(RetentionPolicy.RUNTIME)
@interface ScheduleNonRepeatable1 {
String dayOfMonth() default "First";
String dayOfWeek() default "Mon";
int hour() default 12;
}
@ScheduleNonRepeatable1(dayOfWeek = "Fri", hour = 23)
public class Example1 {
public static void main(final String[] args) {
final Example1 example1 = new Example1();
final Annotation annotation = example1.getClass().
getAnnotation(ScheduleNonRepeatable1.class);
System.out.println(annotation);
}
}
@ScheduleNonRepeatable1(hour=23, dayOfMonth="First", dayOfWeek="Fri")
89/360
JEP-120: Repeating Annotations
https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99
@Retention(RetentionPolicy.RUNTIME)
@interface ScheduleNonRepeatable2 {
String dayOfMonth() default "First";
String dayOfWeek() default "Mon";
int hour() default 12;
}
@ScheduleNonRepeatable2(dayOfMonth = "last")
@ScheduleNonRepeatable2(dayOfWeek = "Fri", hour = 23)
public class Example2 {
public static void main(final String[] args) {
final Example2 example2 = new Example2();
final Annotation annotation = example2.getClass().
getAnnotation(ScheduleNonRepeatable2.class);
System.out.println(annotation);
}
}
90/360
JEP-120: Repeating Annotations
https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99
@Retention(RetentionPolicy.RUNTIME)
@interface ScheduleNonRepeatable2 {
String dayOfMonth() default "First";
String dayOfWeek() default "Mon";
int hour() default 12;
}
@ScheduleNonRepeatable2(dayOfMonth = "last")
@ScheduleNonRepeatable2(dayOfWeek = "Fri", hour = 23)
public class Example2 {
public static void main(final String[] args) {
final Example2 example2 = new Example2();
final Annotation annotation = example2.getClass().
getAnnotation(ScheduleNonRepeatable2.class);
System.out.println(annotation);
}
}
Duplicate annotation of
non-repeatable type
@ScheduleNonRepeatable2
91/360
JEP-120: Repeating Annotations
https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99
@Retention(RetentionPolicy.RUNTIME)
@interface Schedules {
ScheduleRepeatable[] value();
}
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Schedules.class)
@interface ScheduleRepeatable {
String dayOfMonth() default "First";
String dayOfWeek() default "Mon";
int hour() default 12;
}
@ScheduleRepeatable(dayOfMonth = "last")
@ScheduleRepeatable(dayOfWeek = "Fri", hour = 23)
public class Example3 {
public static void main(final String[] args) {
final Example3 example3 = new Example3();
final Annotation annotation = example3.getClass().
getAnnotation(Schedules.class);
System.out.println(annotation);
}
}
92/360
JEP-120: Repeating Annotations
https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99
@Retention(RetentionPolicy.RUNTIME)
@interface Schedules {
ScheduleRepeatable[] value();
}
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Schedules.class)
@interface ScheduleRepeatable {
String dayOfMonth() default "First";
String dayOfWeek() default "Mon";
int hour() default 12;
}
@ScheduleRepeatable(dayOfMonth = "last")
@ScheduleRepeatable(dayOfWeek = "Fri", hour = 23)
public class Example3 {
public static void main(final String[] args) {
final Example3 example3 = new Example3();
final Annotation annotation = example3.getClass().
getAnnotation(Schedules.class);
System.out.println(annotation);
}
}
@Schedules({@ScheduleRepeatable(hour=12, dayOfMonth="last", dayOfWeek="Mon"),
@ScheduleRepeatable(hour=23, dayOfMonth="First", dayOfWeek="Fri")})
93/360
JVM
94/360
JEP-178: Statically-linked JNI
Libraries
 Native programs that embed the JRE
 Java programs running in environments
without shared libraries
 Enable developers to package a Java run-
time, native code, and Java code together
into a single binary
95/360
JEP-122: Permanent Generation
Removal
 “Automatic garbage
collection is [..]
identifying which
objects are in use and
[…] deleting the
unused objects.”
 Remove Permanent
Generation
– No more size tuning
https://openjdk.org/jeps/122
96/360
APIS
97/360
JEP-174: Nashorn JS Engine
 Successor of Mozilla’s Rhino
 100% in ECMAScript v5.1 test suite
 Java 8: Introduced
 Java 11: Deprecated
 Java 15: Removed
98/360
JEP-174: Nashorn JS Engine
 https://github.com/openjdk/nashorn
https://www.baeldung.com/java-nashorn
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn");
final Bindings bindings = engine.createBindings();
bindings.put("name", "Nashorn");
result = engine.eval("var greeting = 'hello world' + name;" + "print(greeting);" + "greeting");
System.out.println(result);
final Invocable invocable = (Invocable) engine;
engine.eval("function composeGreeting(name) {" + "return 'Hello ' + name" + "}");
result = invocable.invokeFunction("composeGreeting", "Nashorn");
System.out.println(result);
result = engine.eval("var HashMap = Java.type('java.util.HashMap’);"
+ "var map = new HashMap();"
+ "map.put('hello', 'world');" + "map");
System.out.println(result);
99/360
JSR-310, JEP-150: Date, Time API
 Need to manipulate dates and times
 Disparate APIs, missing features
– Set time to midnight for a date without a time
 Complete terminology
 Complete, cohesive implementation
– java.time.*
100/360
MISC
101/360
JEP-153: JavaFX Applications
 Three “types” of programs
– Class files
– JAR files
– JavaFX
 Enhance the java command-line to launch
JavaFX programs
102/360
Java 9
2017/09/21
103/360
LANGUAGE
104/360
Private Interface Methods
public interface IA {
int foo();
default int bar() {
return this.bar1();
}
private int bar1() {
return 42;
}
}
public static void main(final String[] args) {
final IA anIA = new IA() {
public int foo() {
return 0;
}
};
System.out.println(anIA.foo());
System.out.println(anIA.bar());
final IA anotherIA = new IA() {
public int foo() {
return IA.super.bar1();
}
public int bar() {
return 0;
}
};
System.out.println(anotherIA.foo());
System.out.println(anotherIA.bar());
}
105/360
Private Interface Methods
public interface IA {
int foo();
default int bar() {
return this.bar1();
}
private int bar1() {
return 42;
}
}
public static void main(final String[] args) {
final IA anIA = new IA() {
public int foo() {
return 0;
}
};
System.out.println(anIA.foo());
System.out.println(anIA.bar());
final IA anotherIA = new IA() {
public int foo() {
return IA.super.bar1();
}
public int bar() {
return 0;
}
};
System.out.println(anotherIA.foo());
System.out.println(anotherIA.bar());
}
0
42
42
0
106/360
JSR-376: Modularization
 JSR-376: Java Platform Module System,
part of Project Jigsaw
– Ease library construction, maintenance
– Security, maintainability of Java (and JDK)
– Allow scaling down programs for small devices
– Improve program compilation and loading times
https://openjdk.org/projects/jigsaw/
107/360
JSR-376: Modularization
 JEP-200: The Modular JDK
 JEP-201: Modular Source Code
 JEP-220: Modular Run-time Images
 JEP-260: Encapsulate Most Internal APIs
 JEP-261: Module System
 JEP-282: jlink: The Java Linker
 JSR 376: Java Platform Module System
108/360
JSR-376: Modularization
 Classpath / JARs Hell
 Version conflicts
 Large Monolithic JDK
 Security Problems
https://www.geeksforgeeks.org/jpms-java-platform-module-system/
109/360
JSR-376: Modularization
 Classpath / JARs Hell
 Version conflicts
– Cf. DLL Hell, no versions, one directory
– One, long list of JAR files
• Run-time missing dependencies
• Order of declaration (shadowing)
 Large Monolithic JDK
 Security Problems
https://www.geeksforgeeks.org/jpms-java-platform-module-system/
110/360
JSR-376: Modularization
 Classpath / JARs Hell
 Version conflicts
 Large Monolithic JDK
– E.g., in Java v1.4.2, RT.jar is 21.8 MB (!)
 Security Problems
https://www.geeksforgeeks.org/jpms-java-platform-module-system/
111/360
JSR-376: Modularization
 Classpath / JARs Hell
 Version conflicts
 Large Monolithic JDK
 Security Problems
– Implementation classes must be public
– Cannot control access to these classes
– padl.kernel vs. padl.kernel.impl
https://www.geeksforgeeks.org/jpms-java-platform-module-system/
112/360
JSR-376: Modularization
 A module is a “package of packages”
– With one module descriptor
– With own resources (data)
 A module descriptor
– Domain Specific Language
– exports, module, open, opens, provides,
requires, to, transitive, uses, and with
113/360
JSR-376: Modularization
Raoul-Gabriel Urma, Mario Fusco, Alan Mycroft ; Modern Java in Action ; Manning, 2018 (Chapter 14)
module com.example.foo {
requires transitive com.example.foo.network;
requires static com.example.foo.http;
requires java.logging;
exports com.example.foo.bar;
exports com.example.foo.internal to
com.example.foo.probe;
opens com.example.foo.quux;
opens com.example.foo.internal to
com.example.foo.network,
com.example.foo.probe;
uses com.example.foo.spi.Intf;
provides com.example.foo.spi.Data with
com.example.foo.Impl;
}
114/360
JSR-376: Modularization
Raoul-Gabriel Urma, Mario Fusco, Alan Mycroft ; Modern Java in Action ; Manning, 2018 (Chapter 14)
module com.example.foo {
requires transitive com.example.foo.network;
requires static com.example.foo.http;
requires java.logging;
exports com.example.foo.bar;
exports com.example.foo.internal to
com.example.foo.probe;
opens com.example.foo.quux;
opens com.example.foo.internal to
com.example.foo.network,
com.example.foo.probe;
uses com.example.foo.spi.Intf;
provides com.example.foo.spi.Data with
com.example.foo.Impl;
}
115/360
JSR-376: Modularization
 Declaration of module
com.example.foo
 Dependencies on
three other modules
– transitive: client
modules also can
access that module
– static: at compile-time,
option at run-time
module com.example.foo {
requires transitive com.example.foo.network;
requires static com.example.foo.http;
requires java.logging;
exports com.example.foo.bar;
exports com.example.foo.internal to
com.example.foo.probe;
opens com.example.foo.quux;
opens com.example.foo.internal to
com.example.foo.network,
com.example.foo.probe;
uses com.example.foo.spi.Intf;
provides com.example.foo.spi.Data with
com.example.foo.Impl;
}
116/360
JSR-376: Modularization
 (Qualified) exports to
other, client modules
– Public types accessible
to all client modules
– Or only to types in
com.example.foo.probe
module com.example.foo {
requires transitive com.example.foo.network;
requires static com.example.foo.http;
requires java.logging;
exports com.example.foo.bar;
exports com.example.foo.internal to
com.example.foo.probe;
opens com.example.foo.quux;
opens com.example.foo.internal to
com.example.foo.network,
com.example.foo.probe;
uses com.example.foo.spi.Intf;
provides com.example.foo.spi.Data with
com.example.foo.Impl;
}
117/360
JSR-376: Modularization
 (Qualified) opening to
other, client modules
at run-time only
– Public types accessible
to all client modules
– Or only to types in com.
example.foo.network or
com.example.foo.probe
– Allows introspection
module com.example.foo {
requires transitive com.example.foo.network;
requires static com.example.foo.http;
requires java.logging;
exports com.example.foo.bar;
exports com.example.foo.internal to
com.example.foo.probe;
opens com.example.foo.quux;
opens com.example.foo.internal to
com.example.foo.network,
com.example.foo.probe;
uses com.example.foo.spi.Intf;
provides com.example.foo.spi.Data with
com.example.foo.Impl;
}
118/360
module com.example.foo {
requires transitive com.example.foo.network;
requires static com.example.foo.http;
requires java.logging;
exports com.example.foo.bar;
exports com.example.foo.internal to
com.example.foo.probe;
opens com.example.foo.quux;
opens com.example.foo.internal to
com.example.foo.network,
com.example.foo.probe;
uses com.example.foo.spi.Intf;
provides com.example.foo.spi.Data with
com.example.foo.Impl;
}
JSR-376: Modularization
 Service consumer
– Interface/abstract class
com.example.foo.spi.Intf
 Service provider
– Interface/abstract class
com.example.foo.spi.Data
– With concrete class
com.example.foo.Impl
119/360
JSR-376: Modularization
 modularisation.Client
– Can access any public
type at compile-time
and at run-time
– Can access some
protected/private
data with introspection
 internal.Client
– Cannot access
HiddenImplementation
120/360
JSR-376: Modularization
 modularisation.Client
– Can access any public
type at compile-time
and at run-time
– Can access some
protected/private
data with introspection
 internal.Client
– Cannot access
HiddenImplementation
Package-protected
Class (not public!)
121/360
JSR-376: Modularization
final Interface aki = new Implementation();
aki.foo();
System.out.println("Call on public implementation: ");
final Class<? extends Interface> implementation1 = Class
.forName(“....impl.Implementation").asSubclass(Interface.class);
final Interface aki1 = implementation1.getDeclaredConstructor().newInstance();
final Method[] methods1 = implementation1.getDeclaredMethods();
for (final Method method : methods1) {
try {
method.setAccessible(true);
method.invoke(aki1, new Object[0]);
} catch (final RuntimeException e) {
System.out.println(e.getMessage());
}
}
final Class<? extends Interface> implementation2 = Class
.forName(“....impl.HiddenImplementation").asSubclass(Interface.class);
final Interface aki2 = implementation2.getDeclaredConstructor().newInstance();
final Method[] methods2 = implementation2.getDeclaredMethods();
for (final Method method : methods2) {
// Same code
122/360
JSR-376: Modularization
 The client code has access to the fields and
methods in all public types, even if private
Direct call: Implementation.bar()
Call on public implementation:
bar: Implementation.bar()
foo: Implementation.bar()
Call on hidden implementation:
Exception in thread "main" java.lang.IllegalAccessException: class
net.ptidej.modularisation.Client cannot access a member of class
net.ptidej.modularisation.kernel.impl.HiddenImplementation with package
access
...
123/360
JSR-376: Modularization
 The client code has access to the fields and
methods in all public types, even if private
Direct call: Implementation.bar()
Call on public implementation:
bar: Implementation.bar()
foo: Implementation.bar()
Call on hidden implementation:
Exception in thread "main" java.lang.IllegalAccessException: class
net.ptidej.modularisation.Client cannot access a member of class
net.ptidej.modularisation.kernel.impl.HiddenImplementation with package
access
...
Including the
private method
124/360
JSR-376: Modularization
 Client
 Provider
module ModularizationWithModulesClient1 {
requires ModularizationWithModulesLibrary1;
}
module ModularizationWithModulesLibrary1 {
exports net.ptidej.modularisation.kernel;
exports net.ptidej.modularisation.kernel.impl;
}
125/360
JSR-376: Modularization
 Client (not a module)
 Client (module)
Direct call: Implementation.bar()
Call on public implementation:
bar: Implementation.bar()
foo: Implementation.bar()
Call on hidden implementation:
Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client
cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation with
package access
Direct call: Implementation.bar()
Call on public implementation:
foo: Implementation.bar()
bar: Unable to make private void net.ptidej.modularisation.kernel.impl.Implementation.bar()
accessible: module ModularizationWithModulesLibrary1 does not "opens
net.ptidej.modularisation.kernel.impl" to module ModularizationWithModulesClient1
Call on hidden implementation:
Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client
(in module ModularizationWithModulesClient1) cannot access a member of class
net.ptidej.modularisation.kernel.impl.HiddenImplementation (in module
ModularizationWithModulesLibrary1) with package access
126/360
JSR-376: Modularization
 Client (not a module)
 Client (module)
Direct call: Implementation.bar()
Call on public implementation:
bar: Implementation.bar()
foo: Implementation.bar()
Call on hidden implementation:
Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client
cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation with
package access
Direct call: Implementation.bar()
Call on public implementation:
foo: Implementation.bar()
bar: Unable to make private void net.ptidej.modularisation.kernel.impl.Implementation.bar()
accessible: module ModularizationWithModulesLibrary1 does not "opens
net.ptidej.modularisation.kernel.impl" to module ModularizationWithModulesClient1
Call on hidden implementation:
Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client
(in module ModularizationWithModulesClient1) cannot access a member of class
net.ptidej.modularisation.kernel.impl.HiddenImplementation (in module
ModularizationWithModulesLibrary1) with package access
Non-module can still
access private methods
127/360
JSR-376: Modularization
 Client (not a module)
 Client (module)
Direct call: Implementation.bar()
Call on public implementation:
bar: Implementation.bar()
foo: Implementation.bar()
Call on hidden implementation:
Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client
cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation with
package access
Direct call: Implementation.bar()
Call on public implementation:
foo: Implementation.bar()
bar: Unable to make private void net.ptidej.modularisation.kernel.impl.Implementation.bar()
accessible: module ModularizationWithModulesLibrary1 does not "opens
net.ptidej.modularisation.kernel.impl" to module ModularizationWithModulesClient1
Call on hidden implementation:
Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client
(in module ModularizationWithModulesClient1) cannot access a member of class
net.ptidej.modularisation.kernel.impl.HiddenImplementation (in module
ModularizationWithModulesLibrary1) with package access
Non-module can still
access private methods
Modules cannot access
private/package data
128/360
JSR-376: Modularization
 Client
 Provider
module ModularizationWithModulesClient2 {
requires ModularizationWithModulesLibrary2;
uses net.ptidej.modularisation.kernel.Interface;
}
module ModularizationWithModulesLibrary2 {
exports net.ptidej.modularisation.kernel;
provides
net.ptidej.modularisation.kernel.Interface with
net.ptidej.modularisation.kernel.impl.Implementation;
}
129/360
JSR-376: Modularization
 Client implementation
 Client output
Implementation.bar()
Call on public implementation:
Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client
(in module ModularizationWithModulesClient2) cannot access class
net.ptidej.modularisation.kernel.impl.Implementation (in module ModularizationWithModulesLibrary2)
because module ModularizationWithModulesLibrary2 does not export
net.ptidej.modularisation.kernel.impl to module ModularizationWithModulesClient2
final ServiceLoader<Interface> providers = ServiceLoader.load(Interface.class);
final Interface aki = providers.findFirst().orElse(null);
aki.foo();
130/360
JSR-376: Modularization
 Client implementation
 Client output
Implementation.bar()
Call on public implementation:
Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client
(in module ModularizationWithModulesClient2) cannot access class
net.ptidej.modularisation.kernel.impl.Implementation (in module ModularizationWithModulesLibrary2)
because module ModularizationWithModulesLibrary2 does not export
net.ptidej.modularisation.kernel.impl to module ModularizationWithModulesClient2
No access to data not
exported/provided,
even if public!
final ServiceLoader<Interface> providers = ServiceLoader.load(Interface.class);
final Interface aki = providers.findFirst().orElse(null);
aki.foo();
131/360
JSR-376: Modularization
https://www.baeldung.com/java-illegal-reflective-access
 Backward compatibility
132/360
JSR-376: Modularization
https://docs.oracle.com/javase%2F9%2Fdocs%2Fapi%2F%2F/overview-summary.html
133/360
JSR-376: Modularization
https://docs.oracle.com/javase%2F9%2Fdocs%2Fapi%2F%2F/java/lang/Module.html
134/360
JSR-376: Modularization
 Relation to OSGi
– Open Service Gateway Initiative
• From 05/2000, latest 12/2020
– Eclipse Foundation open-source project
– Framework for developing and deploying
• Modular programs and libraries
• IoT and other constrained devices
https://www.techtarget.com/searchnetworking/definition/OSGi
135/360
JSR-376: Modularization
OSGi (Bundles)
 Several class loaders
– Cannot be used for the JDK
– Allow “duplicate” packages
– Allow multiple versions
 Visibility
JPMS (Modules)
 One class loader
– Can be used in the JDK
– Disallow same packages
– No versioning
 Accessibility
https://www.infoq.com/articles/java9-osgi-future-modularity/, https://www.infoq.com/articles/java9-osgi-future-modularity-
part-2/, https://www.baeldung.com/java-illegal-reflective-access, https://en.wikipedia.org/wiki/OSGi
136/360
JSR-376: Modularization
OSGi (Bundles)
 “[B]uild dependencies and
runtime dependencies can
and often do differ”
JPMS (Modules)
 “[T]he module system
should […] work [same] at
compile time, run time…”
Export-Package: org.example.foo;
version=1.0.1, org.example.bar;
version=2.1.0
Import-Package: org.example.foo;
version='[1,2)', org.example.bar;
version='[2.0,2.1)'
module A {
exports org.example.foo;
exports org.example.bar;
}
module B {
require A;
}
https://www.infoq.com/articles/java9-osgi-future-modularity/, https://www.infoq.com/articles/java9-osgi-future-modularity-
part-2/, https://www.baeldung.com/java-illegal-reflective-access, https://en.wikipedia.org/wiki/OSGi
137/360
JEP-213: Milling Project Coin
 From Java 7
– Allow @SafeVargs on private instance methods
– Allow effectively-final variables as resources in the try-
with-resources statement
– Allow diamond with anonymous classes in some cases
 From Java 8
– Remove underscore as legal identifier names
 In Java 9
– Support for private methods in interfaces
138/360
JVM
139/360
 Nothing to mention, so much
work went into modularisation
140/360
APIS
141/360
Collection Factory Methods
 No null values
 No modification
– Run-time exception
public class Example1 {
public static void main(final String[] args) {
final List<String> list = List.of("Rick Deckard", "Roy Batty", "Harry Bryant", "Hannibal
Chew", "Gaff", "Holden", "Leon Kowalski", "Taffey Lewis", "Pris", "Rachael", "J.F.
Sebastian", "Dr. Eldon Tyrell", "Zhora", "Hodge", "Mary");
System.out.println(list);
list.add("Paul Atreides");
}
}
142/360
Collection Factory Methods
 No null values
 No modification
– Run-time exception
public class Example1 {
public static void main(final String[] args) {
final List<String> list = List.of("Rick Deckard", "Roy Batty", "Harry Bryant", "Hannibal
Chew", "Gaff", "Holden", "Leon Kowalski", "Taffey Lewis", "Pris", "Rachael", "J.F.
Sebastian", "Dr. Eldon Tyrell", "Zhora", "Hodge", "Mary");
System.out.println(list);
list.add("Paul Atreides");
}
}
[Rick Deckard, Roy Batty, Harry Bryant, [...] Tyrell, Zhora, Hodge, Mary]
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
at [...]
at net.ptidej.newjava.collectionfactories.Example1.main(Example1.java:11)
143/360
JavaDB Removal
 JavaDB was a repackaging of Apache Derby
– Relational database
– Open-source
– Entirely in Java
– Embedded JDBC driver
144/360
JEP-254: Compact Strings
Problem and Solution
 More space-efficient
internal representation
– Not about using UTF-8
 From a UTF-16 char
array to a byte array
with an encoding flag
– ISO-8859-1/Latin-1 (1 byte
per char) or UTF-16 (2 bytes)
– String-related classes and
HotSpot intrinsic operations
Consequences
 Reduction in memory
footprint
 Substantial reductions of
GC activity
 Minor performance
regressions in some
corner cases
145/360
JEP-263: HiDPI Graphics
 Java programs sized and
rendered based on pixels
 HiDPI displays can have 2
to 3 times higher pixel
densities
 Windows Direct2D APIs
 Linux GTK+ 3 libraries
https://stackoverflow.com/questions/52519777/java-swing-app-looks-tiny-on-high-dpi-screen-when-it-should-be-scaled-to-normal
146/360
JEP-266: More on Concurrency
 “[A]synchronous stream processing with
non-blocking back pressure”
– https://www.reactive-streams.org/
https://www.baeldung.com/java-9-reactive-streams
// Given
final SubmissionPublisher<String> publisher = new SubmissionPublisher<>();
final EndSubscriber<String> subscriber = new EndSubscriber<>();
final List<String> items = List.of("1", "x", "2", "x", "3", "x");
// When
publisher.subscribe(subscriber);
items.forEach(publisher::submit);
publisher.close();
// Then
Awaitility.await().atMost(1000, TimeUnit.MILLISECONDS)
.until(() -> subscriber.consumedElements.containsAll(items));
147/360
JEP-268: XML Catalogs
 OASIS XML Catalogs standard, v1.1
– Map XML external identifiers into (local) URIs
 Java API
– javax.xml.catalog.*
<?xml version="1.0"?>
<!DOCTYPE catalog
PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN"
"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public">
<public publicId="-//W3C//DTD XHTML 1.0 Strict//EN"
uri="dtd/xhtml1/xhtml1-strict.dtd"/>
<public publicId="-//W3C//DTD XHTML 1.0 Transitional//EN"
uri="dtd/xhtml1/xhtml1-transitional.dtd"/>
<public publicId="-//W3C//DTD XHTML 1.1//EN"
uri="dtd/xhtml11/xhtml11-flat.dtd"/>
</catalog>
148/360
MISC
149/360
JEP-222: jshell
150/360
JEP-282: jlink
 Assemble, optimize some modules and their
dependencies into a custom run-time image
– JEP-220: Modular run-time images
javac -d out module-info.java
javac -d out --module-path out 
netptidejnewjavajlinkHelloWorld.java
jlink --module-path "%JAVA_HOME%jmods";out 
--add-modules testJLinkModule 
--output CustomJRE
cd CustomJRE/bib/
java --module testJLinkModule/net.ptidej.newjava.jlink.HelloWorld
https://www.baeldung.com/jlink
151/360
JEP-295: jaotc
 Ahead-of-time compilation
– Compile Java classes to native code
before launching the virtual machine
https://stackoverflow.com/questions/45298045/how-do-i-run-a-class-compiled-with-jaotc
javac Test.java
jaotc Test.class
jaotc --output libjava.base.so --module java.base
java -XX:AOTLibrary=./Test.so Test
152/360
Java 10
2018/03/20
153/360
LANGUAGE
154/360
JEP-286: Local-variable Type
Inference
final List<String> list1 = new ArrayList<>();
System.out.println(list1);
final var list2 = new ArrayList<String>();
System.out.println(list2);
vs.
155/360
JVM
156/360
JEP-304: GC Interface
 “Improve the source code isolation of
different garbage collectors by introducing a
clean garbage collector (GC) interface.”
https://medium.com/@unmeshvjoshi/writing-your-own-garbage-collector-for-jdk12-8c83e3d0309b
https://github.com/openjdk/jdk/blob/master/src/hotspot/share/gc/shared/collectedHeap.hpp#L90
class CollectedHeap : public CHeapObj<mtGC> {
virtual jint initialize() = 0;
virtual HeapWord* allocate_new_tlab(size_t min_size,
size_t requested_size,
size_t* actual_size) = 0;
virtual HeapWord* mem_allocate(size_t size,
bool* gc_overhead_limit_was_exceeded) = 0;
// ...
157/360
JEP-307: Parallel Full GC
 Improve G1 worst-case with full parallel GC
– Before Java 9: Parallel GC
– Since Java 9: G1
https://dev.java/evolution/
158/360
JEP-310: Application Class-Data
Sharing
 Improve startup and footprint
https://www.geeksforgeeks.org/class-data-sharing-in-java/
java -XX:+UnlockCommercialFeatures-XX:+UseAppCDS
-XX:DumpLoadedClassList=LoadedClasses.1st -jar AppCDS.jar
java -XX:+UnlockCommercialFeatures -Xshare:dump -XX:+UseAppCDS
-XX:SharedClassListFile=LoadedClasses.1st
-XX:SharedArchiveFile=CustomSharedArchive.jsa -cp AppCDS.jar
java -XX:UnlockCommercialFeatures -verbose -XShare:on
-XX:+UseAppCDS -XX:SharedArchiveFile=CUstomSharedArchive.jsa
-jar AppCDS.jar
159/360
JEP-312: Thread-local Handshakes
 Callback on threads without performing a
global VM safepoint
 Possible and cheap to stop individual
threads and not just all threads
-XX:ThreadLocalHandshakes=<true|false>
160/360
JEP-316: Heap Allocation on
Alternative Memory Devices
 Availability of cheap NVDIMM memory
– Non Volatile Dual In-line Memory Module
https://blog.workinghardinit.work/2019/07/18/a-quick-intro-to-nvdimm-n/
-XX:AllocateHeapAt=<path>
161/360
JEP-317: Experimental Java-based
JIT Compiler
 Efficient JIT compiler
for Java in Java
 As of 18/09/30
https://www.graalvm.org/
https://www.javacodegeeks.com/2018/10/java-graalvm-database-stream-performance.html
-XX:+UnlockExperimentalVMOptions
-XX:+UseJVMCICompiler
162/360
APIS
163/360
JEP-314: Additional Unicode
Language-Tag Extensions
 BCP 47 language tags
– Codes to identify languages
• en: English
• en-US: English, in United States
• km-Khmr-KH: Khmer, in Khmer script, in Cambodia
• km-fonipa: Khmer, transcribed in IPA
 Changes to many APIs
– java.text.DateFormat, java.util.Currency,
java.time.format.DateTimeFormatter, …
https://help.keyman.com/developer/current-version/reference/bcp-47
164/360
MISC
165/360
JEP-296: Consolidated JDK Forest
 Until Java 9
– Eight repos: root, corba, hotspot, jaxp, jaxws,
jdk, langtools, and nashorn
 Since Java 10
– One unified repository
$ROOT/jdk/src/java.base
...
$ROOT/langtools/src/java.compiler
...
166/360
JEP-296: Consolidated JDK Forest
 Until Java 9
– Eight repos: root, corba, hotspot, jaxp, jaxws,
jdk, langtools, and nashorn
 Since Java 10
– One unified repository
$ROOT/jdk/src/java.base
...
$ROOT/langtools/src/java.compiler
...
$ROOT/src/java.base
$ROOT/src/java.compiler
...
167/360
JEP-313: Native-Header Generation
Tool Removal
 javah features (and more) now in javac
javac HelloWorld.java
javah HelloWorld
javac -h jni -d bin HelloWorld.java
vs.
168/360
JEP-319: Root Certificates
 Default set of root Certification Authority
(CA) certificates
– Oracle Java SE Root CA becomes open source
– OpenJDK can use the same certificates
169/360
JEP-322: Time-based Release
Versioning
 New version scheme
final Version version = Runtime.version();
System.out.println(version);
System.out.print("Feature: ");
System.out.println(version.feature());
System.out.print("Interim: ");
System.out.println(version.interim());
System.out.print("Update: ");
System.out.println(version.update());
System.out.print("Patch: ");
System.out.println(version.patch());
System.out.print("Build: ");
System.out.println(version.build());
System.out.print("Optional: ");
System.out.println(version.optional());
System.out.print("Pre: ");
System.out.println(version.pre());
170/360
JEP-322: Time-based Release
Versioning
 New version scheme
final Version version = Runtime.version();
System.out.println(version);
System.out.print("Feature: ");
System.out.println(version.feature());
System.out.print("Interim: ");
System.out.println(version.interim());
System.out.print("Update: ");
System.out.println(version.update());
System.out.print("Patch: ");
System.out.println(version.patch());
System.out.print("Build: ");
System.out.println(version.build());
System.out.print("Optional: ");
System.out.println(version.optional());
System.out.print("Pre: ");
System.out.println(version.pre());
21.0.1+12-LTS-29
Feature: 21
Interim: 0
Update: 1
Patch: 0
Build: Optional[12]
Optional: Optional[LTS-29]
Pre: Optional.empty
171/360
Java 11
2018/09/25
172/360
LANGUAGE
173/360
JEP-181: Nest-based Access Control
 Before Java 11
– Bridge method, e.g.,
access$000(Example1)
 Since Java 11
– Direct access
– Access to nest mates’
private members
https://mkyong.com/java/java-11-nest-based-access-control/
public class Example1 {
private String name = "I'm Example1!";
public class A {
public void printName() {
System.out.println(name);
}
}
public class B {
public void printName() {
System.out.println(Example1.this.name);
}
public class B1 {
public void printName() {
System.out.println(Example1.this.name);
}
}
}
public static void main(final String[] args) {
final Example1 e1 = new Example1();
final Example1.B b = e1.new B();
final Example1.B.B1 b1 = b.new B1();
b1.printName();
}
}
174/360
JEP-181: Nest-based Access Control
https://mkyong.com/java/java-11-nest-based-access-control/
public class Example2 {
private String name = "I'm Example2!";
public class A {
public void printName() {
System.out.println(name);
}
}
public class B {
public void printName() {
System.out.println(Example2.this.name);
}
public class B1 {
public void printName() {
System.out.println(Example2.this.name);
}
}
}
public static void main(final String[] args) {
System.out.println(A.class.getNestHost());
System.out.println(A.class.isNestmateOf(B.class));
for (final Class<?> clazz : Example2.B.class.getNestMembers()) {
System.out.println(clazz);
}
}
}
175/360
JEP-181: Nest-based Access Control
https://mkyong.com/java/java-11-nest-based-access-control/
public class Example2 {
private String name = "I'm Example2!";
public class A {
public void printName() {
System.out.println(name);
}
}
public class B {
public void printName() {
System.out.println(Example2.this.name);
}
public class B1 {
public void printName() {
System.out.println(Example2.this.name);
}
}
}
public static void main(final String[] args) {
System.out.println(A.class.getNestHost());
System.out.println(A.class.isNestmateOf(B.class));
for (final Class<?> clazz : Example2.B.class.getNestMembers()) {
System.out.println(clazz);
}
}
}
class net.ptidej.newjava.nest.Example2
true
class net.ptidej.newjava.nest.Example2
class net.ptidej.newjava.nest.Example2$A
class net.ptidej.newjava.nest.Example2$B
class net.ptidej.newjava.nest.Example2$B$B1
176/360
JEP-323: Local-variable Syntax for
Lambda Parameters
interface Comparator<T> {
int compare(final T a, final T b);
}
public class Example1 {
public static void main(final String[] args) {
final Comparator<String> comparator1 = new Comparator<>() {
@Override
public int compare(final String a, final String b) {
return a.compareTo(b);
}
};
System.out.println(comparator1.compare("Hello", "World"));
final Comparator<String> comparator2 = (a, b) -> a.compareTo(b);
System.out.println(comparator2.compare("Hello", "World"));
final Comparator<String> comparator3 = (String a, String b) -> a.compareTo(b);
System.out.println(comparator3.compare("Hello", "World"));
final Comparator<String> comparator4 = (final var a, final var b) -> a.compareTo(b);
System.out.println(comparator4.compare("Hello", "World"));
final Comparator<String> comparator5 = (@NonNull var a, @NonNull var b) -> a.compareTo(b);
System.out.println(comparator5.compare("Hello", "World"));
}
}
177/360
JEP-323: Local-variable Syntax for
Lambda Parameters
interface Comparator<T> {
int compare(final T a, final T b);
}
public class Example1 {
public static void main(final String[] args) {
final Comparator<String> comparator1 = new Comparator<>() {
@Override
public int compare(final String a, final String b) {
return a.compareTo(b);
}
};
System.out.println(comparator1.compare("Hello", "World"));
final Comparator<String> comparator2 = (a, b) -> a.compareTo(b);
System.out.println(comparator2.compare("Hello", "World"));
final Comparator<String> comparator3 = (String a, String b) -> a.compareTo(b);
System.out.println(comparator3.compare("Hello", "World"));
final Comparator<String> comparator4 = (final var a, final var b) -> a.compareTo(b);
System.out.println(comparator4.compare("Hello", "World"));
final Comparator<String> comparator5 = (@NonNull var a, @NonNull var b) -> a.compareTo(b);
System.out.println(comparator5.compare("Hello", "World"));
}
}
Now posssible
178/360
JVM
179/360
JEP-309: Dynamic .class Constants
 Extend the class-file format with a new
constant-pool form
– CONSTANT_Dynamic
 Avoid initialising “expansive” values
– Also, no need to use volatile
https://www.javacodegeeks.com/2018/08/hands-on-java-constantdynamic.html
180/360
JEP-309: Dynamic .class Constants
Problem: How to share some “expensive” data
among different threads?
Solution: Singleton design pattern
public class SomeExpensiveData {
public SomeExpensiveData() {
// Some very expensive (time, space) data to create
System.out.println("tSomeExpensiveData instance created");
}
}
181/360
JEP-309: Dynamic .class Constants
public class MyCallable implements Callable<SomeExpensiveData> {
private static MyCallable UniqueInstance;
public static MyCallable getInstance() {
if (MyCallable.UniqueInstance == null) {
synchronized (MyCallable.class) {
if (MyCallable.UniqueInstance == null) {
MyCallable.UniqueInstance = new MyCallable();
}
}
}
return MyCallable.UniqueInstance;
}
private volatile SomeExpensiveData someExpensiveData;
private MyCallable() {
this.someExpensiveData = new SomeExpensiveData();
}
@Override
public SomeExpensiveData call() throws Exception {
return this.someExpensiveData;
}
}
182/360
JEP-309: Dynamic .class Constants
public class MyCallable implements Callable<SomeExpensiveData> {
private static MyCallable UniqueInstance;
public static MyCallable getInstance() {
if (MyCallable.UniqueInstance == null) {
synchronized (MyCallable.class) {
if (MyCallable.UniqueInstance == null) {
MyCallable.UniqueInstance = new MyCallable();
}
}
}
return MyCallable.UniqueInstance;
}
private volatile SomeExpensiveData someExpensiveData;
private MyCallable() {
this.someExpensiveData = new SomeExpensiveData();
}
@Override
public SomeExpensiveData call() throws Exception {
return this.someExpensiveData;
}
}
Not a true constant
No caching, etc.
183/360
JEP-309: Dynamic .class Constants
public class MyCallable implements Callable<SomeExpensiveData> {
private static MyCallable UniqueInstance;
public static MyCallable getInstance() {
if (MyCallable.UniqueInstance == null) {
synchronized (MyCallable.class) {
if (MyCallable.UniqueInstance == null) {
MyCallable.UniqueInstance = new MyCallable();
}
}
}
return MyCallable.UniqueInstance;
}
private volatile SomeExpensiveData someExpensiveData;
private MyCallable() {
this.someExpensiveData = new SomeExpensiveData();
}
@Override
public SomeExpensiveData call() throws Exception {
return this.someExpensiveData;
}
}
Not a true constant
No caching, etc.
Eager initialisation
184/360
JEP-309: Dynamic .class Constants
 Dynamic constants
– Created once at run-time
– Can be shared among threads
– Can be cached, optimised, etc.
Problem: How to create dynamically a constant
Solution: CONSTANT_Dynamic
185/360
JEP-309: Dynamic .class Constants
 Dynamic constants, javac vs. java
– Cannot be created from source code
• As of 24/03/24
– Can be created in the byte code
 Byte code generation, manipulation library
– Create, modify Java classes at run-time
186/360
JEP-309: Dynamic .class Constants
final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class)
.method(ElementMatchers.named("call")).intercept(FixedValue.value(
JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make();
final Constructor<? extends Callable> loaded =
unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor();
final Callable<SomeExpensiveData> first = loaded.newInstance();
final Callable<SomeExpensiveData> second = loaded.newInstance();
System.out.println("tCallable instances created");
assertThat(first.call()).isEqualTo(second.call());
187/360
JEP-309: Dynamic .class Constants
final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class)
.method(ElementMatchers.named("call")).intercept(FixedValue.value(
JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make();
final Constructor<? extends Callable> loaded =
unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor();
final Callable<SomeExpensiveData> first = loaded.newInstance();
final Callable<SomeExpensiveData> second = loaded.newInstance();
System.out.println("tCallable instances created");
assertThat(first.call()).isEqualTo(second.call());
test_CONSTANT_Dynamic()
Callable instances created
SomeExpensiveData instance created
188/360
JEP-309: Dynamic .class Constants
final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class)
.method(ElementMatchers.named("call")).intercept(FixedValue.value(
JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make();
final Constructor<? extends Callable> loaded =
unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor();
final Callable<SomeExpensiveData> first = loaded.newInstance();
final Callable<SomeExpensiveData> second = loaded.newInstance();
System.out.println("tCallable instances created");
assertThat(first.call()).isEqualTo(second.call());
test_CONSTANT_Dynamic()
Callable instances created
SomeExpensiveData instance created
Lazy initialisation: two
instances created, but not
SomExpensiveData
189/360
JEP-309: Dynamic .class Constants
final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class)
.method(ElementMatchers.named("call")).intercept(FixedValue.value(
JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make();
final Constructor<? extends Callable> loaded =
unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor();
final Callable<SomeExpensiveData> first = loaded.newInstance();
final Callable<SomeExpensiveData> second = loaded.newInstance();
System.out.println("tCallable instances created");
assertThat(first.call()).isEqualTo(second.call());
test_CONSTANT_Dynamic()
Callable instances created
SomeExpensiveData instance created
Lazy initialisation: two
instances created, but not
SomExpensiveData
SomExpensiveData created
only once, with first call()
190/360
JEP-309: Dynamic .class Constants
final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class)
.method(ElementMatchers.named("call")).intercept(FixedValue.value(
JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make();
final Constructor<? extends Callable> loaded =
unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor();
final Callable<SomeExpensiveData> first = loaded.newInstance();
final Callable<SomeExpensiveData> second = loaded.newInstance();
System.out.println("tCallable instances created");
assertThat(first.call()).isEqualTo(second.call());
// (version 17 : 61.0, super bit)
public class net.bytebuddy.[...].Callable$ByteBuddy$7xbn1EIQ implements java.util.concurrent.Callable
public java.lang.Object call() throws java.lang.Exception;
0 ldc <Dynamic> 0 _ net.ptidej.newjava.constantdynamic.SomeExpensiveData [28]
2 areturn
public Callable$ByteBuddy$7xbn1EIQ();
0 aload_0 [this]
1 invokespecial java.lang.Object() [29]
4 return
Bootstrap methods:
0 : # 24 invokestatic java/lang/invoke/ConstantBootstraps.invoke:([...])Ljava/lang/Object;
Method arguments:
#17 net/ptidej/newjava/constantdynamic/SomeExpensiveData.<init>:()V
191/360
JEP-309: Dynamic .class Constants
final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class)
.method(ElementMatchers.named("call")).intercept(FixedValue.value(
JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make();
final Constructor<? extends Callable> loaded =
unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor();
final Callable<SomeExpensiveData> first = loaded.newInstance();
final Callable<SomeExpensiveData> second = loaded.newInstance();
System.out.println("tCallable instances created");
assertThat(first.call()).isEqualTo(second.call());
// (version 17 : 61.0, super bit)
public class net.bytebuddy.[...].Callable$ByteBuddy$7xbn1EIQ implements java.util.concurrent.Callable
public java.lang.Object call() throws java.lang.Exception;
0 ldc <Dynamic> 0 _ net.ptidej.newjava.constantdynamic.SomeExpensiveData [28]
2 areturn
public Callable$ByteBuddy$7xbn1EIQ();
0 aload_0 [this]
1 invokespecial java.lang.Object() [29]
4 return
Bootstrap methods:
0 : # 24 invokestatic java/lang/invoke/ConstantBootstraps.invoke:([...])Ljava/lang/Object;
Method arguments:
#17 net/ptidej/newjava/constantdynamic/SomeExpensiveData.<init>:()V
CONSTANT_Dynamic
with bootstrap method
192/360
JEP-331: Low-overhead Heap
Profiling
 Since Java 6
– No more JVM Profiler
Interface (JVMPI)
– No more JVM Debug
Interface (JVMDI)
– Replaced by JVM Tool
Interface (JVMTI)
 Sampling of Java heap
allocations
– All allocations
– Low-overhead
– Well-defined API
– Live, dead objects
https://docs.oracle.com/en/java/javase/11/docs/specs/jvmti.html
193/360
JEP-331: Low-overhead Heap
Profiling
https://docs.dynatrace.com/docs/platform-modules/applications-and-microservices/profiling-and-optimization/memory-profiling
194/360
JEP-333: Scalable Low-latency GC
 Z Garbage Collector
– GC pause no more than 10ms
– Handle megabyte to terabyte heaps
– No more than 15% throughput reduction wrt. G1
– Foundation for future features and optimisations
– (Only on 64bit operating systems)
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
195/360
APIS
196/360
JEP-320: Java EE and CORBA
Modules Removal
 Since Java 1.2
– OMG CORBA API
– ORB implementation
– CosNaming implementation
– idlj compiler
– Support for IDL and IIOP in rmic compiler
– No significant interest in CORBA anymore
 Since Java 6
– Full Web Services stack
– Now available from third parties
 Deprecated in Java 9
197/360
JEP-321: HTTP Client
 Problems with HttpURLConnection API
– Designed for (now dead) protocols (gopher…)
– Designed before HTTP/1.1
– Too abstract
– Hard to use
– Badly documented
– Blocking mode only
– Very hard maintenance
198/360
JEP-321: HTTP Client
 Three core classes
– HttpClient as a container for configuration
information common to multiple requests
– HttpRequest for requests sent by HttpClient
– HttpResponse for the result of an HttpRequest
https://www.baeldung.com/java-9-http-client
199/360
JEP-321:
https://www.baeldung.com/java-9-http-client
final HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://postman-echo.com/get"))
.version(HttpClient.Version.HTTP_2)
.timeout(Duration.ofSeconds(10))
.header("key1", "value1")
.header("key2", "value2")
.GET()
.build();
final HttpClient client = HttpClient.newHttpClient();
final HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
200/360
JEP-321:
https://www.baeldung.com/java-9-http-client
final HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("https://postman-echo.com/get"))
.version(HttpClient.Version.HTTP_2)
.timeout(Duration.ofSeconds(10))
.header("key1", "value1")
.header("key2", "value2")
.GET()
.build();
final HttpClient client = HttpClient.newHttpClient();
final HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
{
"args": {},
"headers": {
"x-forwarded-proto": "https",
"x-forwarded-port": "443",
"host": "postman-echo.com",
"x-amzn-trace-id": "Root=1-660163f4-038cfd7075f93fad1e79f19e",
"key1": "value1",
"key2": "value2",
"user-agent": "Java-http-client/21.0.1"
},
"url": "https://postman-echo.com/get"
}
201/360
JEP-327: Unicode 10
 Major version of the Unicode Standard
 Support
– Character and String in java.lang
– NumericShaper in java.awt.font
– Bidi, BreakIterator, Normalizer in java.text
202/360
JEP-335: Nashorn Deprecation
 Since Java 8
– JEP-174
 ECMAScript changes rapidly
– Language
– APIs
 Maintenance challenges
– Deprecate Nashorn, its APIs, and jjs
203/360
MISC
204/360
JEP-328: Flight Recorder
 Monitoring tool
– Collects information about the events in a JVM
– An event
• Name
• Timestamp
• Other data
– Thread data, state of the heap, etc.
https://www.baeldung.com/java-flight-recorder-monitoring
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
-XX:StartFlightRecording=duration=200s,filename=flight.jfr
205/360
JEP-328: Flight Recorder
https://www.baeldung.com/java-flight-recorder-monitoring
206/360
JEP-330: Single-file Source-code
Programs Launching
 Lower the (early) learning curve
– But no dependency management
java –cp some.jar HelloWorld.java
207/360
JEP-336: Pack200 Tools and API
Deprecation
 Since Java 5
– Compression scheme for JAR files
– To accommodate 56k modems
 Since Java 9 (and JEP-220)
– Modules
– Compression
– No more applets
– Maintenance challenges
– Modularisation challenges
208/360
Java 12
2019/03/19
209/360
LANGUAGE
210/360
 Nothing to mention?
211/360
JVM
212/360
JEP-344: Abortable Mixed
Collections
 Ability for G1 to abort its collection pauses
 G1 predicts the number of regions to collect
and proceeds only with abortable ones
 Lower pause latency and higher probability
to achieve pause-time target
https://blogs.oracle.com/javamagazine/post/understanding-the-jdks-new-superfast-garbage-collectors
-XX:G1MixedGCCountTarget=<number of mixed garbage collections>
213/360
JEP-346: Unused Committed
Memory Prompt Return
 G1 automatically returns heap memory to
the operating system when idle
-XX:G1PeriodicGCInterval=<true|false>
-XX:G1PeriodicGCInvokesConcurrent=<true|false>
-XX:G1PeriodicGCSystemLoadThreshold=<average 1-minute system load>
214/360
APIS
215/360
JEP-334: JVM Constants API
 API to describes some class-file and run-
time elements (e.g., constants)
https://iampravo.medium.com/java-12-features-and-highlights-81938474cd31
public class Example1 {
public static void main(final String[] args) {
final ClassDesc example1ClassDesc = ClassDesc.of("[...].constantsapi", "Example1");
final MethodTypeDesc mainMethodTypeDesc = MethodTypeDesc.of(example1ClassDesc);
final MethodHandleDesc mainMethodHandleDesc = MethodHandleDesc.ofMethod(
DirectMethodHandleDesc.Kind.STATIC, example1ClassDesc, "main", mainMethodTypeDesc);
System.out.println("Class descriptor: " + example1ClassDesc);
System.out.println("Method type descriptor: " + mainMethodTypeDesc);
System.out.println("Method handle descriptor: " + mainMethodHandleDesc);
}
}
216/360
JEP-334: JVM Constants API
 API to describes some class-file and run-
time elements (e.g., constants)
https://iampravo.medium.com/java-12-features-and-highlights-81938474cd31
public class Example1 {
public static void main(final String[] args) {
final ClassDesc example1ClassDesc = ClassDesc.of("[...].constantsapi", "Example1");
final MethodTypeDesc mainMethodTypeDesc = MethodTypeDesc.of(example1ClassDesc);
final MethodHandleDesc mainMethodHandleDesc = MethodHandleDesc.ofMethod(
DirectMethodHandleDesc.Kind.STATIC, example1ClassDesc, "main", mainMethodTypeDesc);
System.out.println("Class descriptor: " + example1ClassDesc);
System.out.println("Method type descriptor: " + mainMethodTypeDesc);
System.out.println("Method handle descriptor: " + mainMethodHandleDesc);
}
}
Class descriptor: ClassDesc[Example1]
Method type descriptor: MethodTypeDesc[()Example1]
Method handle descriptor: MethodHandleDesc[STATIC/Example1::main()Example1]
217/360
MISC
218/360
JEP-230: Microbenchmark Suite
 Java Microbenchmark Harness (JMH)
– An annotation-based DSL
• @State, @Fork, @Warmup, @Measurement, @Benchmark…
 Microbenchmarks suite integrated into
OpenJDK source code
https://cl4es.github.io/2018/11/16/JEP-230-Microbenchmarks-Suite.html
make build-microbenchmark
219/360
JEP-230: Microbenchmark Suite
 Java Microbenchmark Harness (JMH)
– An annotation-based DSL
• @State, @Fork, @Warmup, @Measurement, @Benchmark…
 Microbenchmarks suite integrated into
OpenJDK source code
https://cl4es.github.io/2018/11/16/JEP-230-Microbenchmarks-Suite.html
make build-microbenchmark
build/$PROFILE/images/test/micro/benchmarks.jar
220/360
JEP-230: Microbenchmark Suite
 Run one java.util.UUIDBench benchmark
– https://github.com/openjdk/jdk/blob/master/test/mi
cro/org/openjdk/bench/java/util/UUIDBench.java
https://cl4es.github.io/2021/01/04/Investigating-MD5-Overheads.html
make test TEST=micro:UUIDBench.fromType3Bytes
221/360
JEP-230: Microbenchmark Suite
 Run one java.util.UUIDBench benchmark
– https://github.com/openjdk/jdk/blob/master/test/mi
cro/org/openjdk/bench/java/util/UUIDBench.java
https://cl4es.github.io/2021/01/04/Investigating-MD5-Overheads.html
make test TEST=micro:UUIDBench.fromType3Bytes
Benchmark Score Error Units
fromType3Bytes 1.460 ± 0.089 ops/us
222/360
JEP-230: Microbenchmark Suite
 Benchmarking the
JVM is difficult
– Just-in-time compiler
– Dead code elimination
– Loop unrolling
– Method inlining
– …
– Warmup iterations
– Iteration durations
– …
https://www.oracle.com/technical-resources/articles/java/architect-benchmarking.html
223/360
Java 13
2019/09/17
2019/09/17
2019/09/17
2019/09/17
224/360
LANGUAGE
225/360
 Nothing to mention?
226/360
JVM
227/360
JEP-351: Unused Memory
Uncommit
 ZGC automatically returns heap memory to
the operating system when idle
– Cf. JEP-346
-XX:ZUncommitDelay=<seconds>
228/360
APIS
229/360
JEP-353: Legacy Socket API
Reimplementation
 Reimplementations
– java.net.Socket
– java.net.ServerSocket
 Simpler, modern
 Easier to maintain, debug
 Ready for user-mode threads
– Fibers, Project Loom
230/360
MISC
231/360
 Nothing to mention?
232/360
Java 14
2020/03/17
233/360
LANGUAGE
234/360
-XX:+ShowCodeDetailsInExceptionMessages
JEP-358: Helpful
NullPointerExceptions
 Describe precisely which variable was null
class Employee {
String getName() {
// return "Bob";
return null;
}
}
public class Example1 {
public static void main(final String[] args) {
final Employee e = new Employee();
e.getName().toString();
}
}
235/360
-XX:+ShowCodeDetailsInExceptionMessages
JEP-358: Helpful
NullPointerExceptions
 Describe precisely which variable was null
class Employee {
String getName() {
// return "Bob";
return null;
}
}
public class Example1 {
public static void main(final String[] args) {
final Employee e = new Employee();
e.getName().toString();
}
}
Exception in thread "main" java.lang.NullPointerException
at net.ptidej.newjava.helpfulnullpointerexceptions.Example1.main(Example1.java:13)
236/360
-XX:+ShowCodeDetailsInExceptionMessages
JEP-358: Helpful
NullPointerExceptions
 Describe precisely which variable was null
class Employee {
String getName() {
// return "Bob";
return null;
}
}
public class Example1 {
public static void main(final String[] args) {
final Employee e = new Employee();
e.getName().toString();
}
}
Exception in thread "main" java.lang.NullPointerException
at net.ptidej.newjava.helpfulnullpointerexceptions.Example1.main(Example1.java:13)
Exception in thread "main" java.lang.NullPointerException: Cannot invoke
"String.toString()" because the return value of "[...].Employee.getName()" is null
at net.ptidej.newjava.helpfulnullpointerexceptions.Example1.main(Example1.java:13)
237/360
JEP-361: switch Expressions
https://medium.com/@imagarg/switch-expression-jep-361-3b5649ec36c9
private static int getDayLength(final Day day) {
int numberOfCharacters = 0;
switch (day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numberOfCharacters = 6;
break;
case TUESDAY:
numberOfCharacters = 7;
break;
case THURSDAY:
case SATURDAY:
numberOfCharacters = 8;
break;
case WEDNESDAY:
numberOfCharacters = 9;
break;
default:
throw new IllegalArgumentException();
}
return numberOfCharacters;
}
private static int getDayLength(final Day day) {
int result = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
default ->
throw new IllegalArgumentException();
};
return result;
}
enum Day {
MONDAY, TUESDAY,
WEDNESDAY,
THURSDAY, FRIDAY,
SATURDAY, SUNDAY;
}
238/360
JVM
239/360
JEP-345: NUMA-Aware Memory
Allocation
 NUMA-aware memory
allocation to increase
G1 performance
– Non-uniform memory
access
– Multi-socket computers
• E.g., HP Z820
-XX:UseParallelGC=<true|false>
240/360
JEP-345: NUMA-Aware Memory
Allocation
 NUMA-aware memory
allocation to increase
G1 performance
– Non-uniform memory
access
– Multi-socket computers
• E.g., HP Z820
-XX:UseParallelGC=<true|false>
Two CPUs, with
their own DIMMs
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22

More Related Content

Similar to Evolution and Examples of Java Features, from Java 1.7 to Java 22

Laurens Van Den Oever Xopus Presentation
Laurens Van Den Oever Xopus PresentationLaurens Van Den Oever Xopus Presentation
Laurens Van Den Oever Xopus PresentationAjax Experience 2009
 
DevNexus 2020: Discover Modern Java
DevNexus 2020: Discover Modern JavaDevNexus 2020: Discover Modern Java
DevNexus 2020: Discover Modern JavaHenri Tremblay
 
Appium TestNG Framework and Multi-Device Automation Execution
Appium TestNG Framework and Multi-Device Automation ExecutionAppium TestNG Framework and Multi-Device Automation Execution
Appium TestNG Framework and Multi-Device Automation ExecutionpCloudy
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVMRafael Winterhalter
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Generating characterization tests for legacy code
Generating characterization tests for legacy codeGenerating characterization tests for legacy code
Generating characterization tests for legacy codeJonas Follesø
 
Introduction to the Java bytecode - So@t - 20130924
Introduction to the Java bytecode - So@t - 20130924Introduction to the Java bytecode - So@t - 20130924
Introduction to the Java bytecode - So@t - 20130924yohanbeschi
 
Владимир Иванов. Java 8 и JVM: что нового в HotSpot
Владимир Иванов. Java 8 и JVM: что нового в HotSpotВладимир Иванов. Java 8 и JVM: что нового в HotSpot
Владимир Иванов. Java 8 и JVM: что нового в HotSpotVolha Banadyseva
 
Java 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from OredevJava 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from OredevMattias Karlsson
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 

Similar to Evolution and Examples of Java Features, from Java 1.7 to Java 22 (20)

Introduzione al TDD
Introduzione al TDDIntroduzione al TDD
Introduzione al TDD
 
Laurens Van Den Oever Xopus Presentation
Laurens Van Den Oever Xopus PresentationLaurens Van Den Oever Xopus Presentation
Laurens Van Den Oever Xopus Presentation
 
DevNexus 2020: Discover Modern Java
DevNexus 2020: Discover Modern JavaDevNexus 2020: Discover Modern Java
DevNexus 2020: Discover Modern Java
 
JUnit 5
JUnit 5JUnit 5
JUnit 5
 
Appium TestNG Framework and Multi-Device Automation Execution
Appium TestNG Framework and Multi-Device Automation ExecutionAppium TestNG Framework and Multi-Device Automation Execution
Appium TestNG Framework and Multi-Device Automation Execution
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVM
 
Java 7: Quo vadis?
Java 7: Quo vadis?Java 7: Quo vadis?
Java 7: Quo vadis?
 
Project Coin
Project CoinProject Coin
Project Coin
 
Rx workshop
Rx workshopRx workshop
Rx workshop
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Generating characterization tests for legacy code
Generating characterization tests for legacy codeGenerating characterization tests for legacy code
Generating characterization tests for legacy code
 
Introduction to the Java bytecode - So@t - 20130924
Introduction to the Java bytecode - So@t - 20130924Introduction to the Java bytecode - So@t - 20130924
Introduction to the Java bytecode - So@t - 20130924
 
Using zone.js
Using zone.jsUsing zone.js
Using zone.js
 
Java 7 New Features
Java 7 New FeaturesJava 7 New Features
Java 7 New Features
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
Владимир Иванов. Java 8 и JVM: что нового в HotSpot
Владимир Иванов. Java 8 и JVM: что нового в HotSpotВладимир Иванов. Java 8 и JVM: что нового в HotSpot
Владимир Иванов. Java 8 и JVM: что нового в HotSpot
 
Java 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from OredevJava 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from Oredev
 
Beyond java8
Beyond java8Beyond java8
Beyond java8
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 

More from Yann-Gaël Guéhéneuc

Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5Yann-Gaël Guéhéneuc
 
Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1Yann-Gaël Guéhéneuc
 
Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3Yann-Gaël Guéhéneuc
 
Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9Yann-Gaël Guéhéneuc
 
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...Yann-Gaël Guéhéneuc
 
An Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its ConsequencesAn Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its ConsequencesYann-Gaël Guéhéneuc
 
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)Yann-Gaël Guéhéneuc
 
On Java Generics, History, Use, Caveats v1.1
On Java Generics, History, Use, Caveats v1.1On Java Generics, History, Use, Caveats v1.1
On Java Generics, History, Use, Caveats v1.1Yann-Gaël Guéhéneuc
 
On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6Yann-Gaël Guéhéneuc
 

More from Yann-Gaël Guéhéneuc (20)

Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5
 
Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1
 
Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3
 
Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9
 
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
 
An Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its ConsequencesAn Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its Consequences
 
Are CPUs VMs Like Any Others? v1.0
Are CPUs VMs Like Any Others? v1.0Are CPUs VMs Like Any Others? v1.0
Are CPUs VMs Like Any Others? v1.0
 
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
 
Well-known Computer Scientists v1.0.2
Well-known Computer Scientists v1.0.2Well-known Computer Scientists v1.0.2
Well-known Computer Scientists v1.0.2
 
On Java Generics, History, Use, Caveats v1.1
On Java Generics, History, Use, Caveats v1.1On Java Generics, History, Use, Caveats v1.1
On Java Generics, History, Use, Caveats v1.1
 
On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6
 
ICSOC'21
ICSOC'21ICSOC'21
ICSOC'21
 
Vissoft21.ppt
Vissoft21.pptVissoft21.ppt
Vissoft21.ppt
 
Service computation20.ppt
Service computation20.pptService computation20.ppt
Service computation20.ppt
 
Serp4 iot20.ppt
Serp4 iot20.pptSerp4 iot20.ppt
Serp4 iot20.ppt
 
Msr20.ppt
Msr20.pptMsr20.ppt
Msr20.ppt
 
Iwesep19.ppt
Iwesep19.pptIwesep19.ppt
Iwesep19.ppt
 
Icsoc20.ppt
Icsoc20.pptIcsoc20.ppt
Icsoc20.ppt
 
Icsoc18.ppt
Icsoc18.pptIcsoc18.ppt
Icsoc18.ppt
 
Icsm20.ppt
Icsm20.pptIcsm20.ppt
Icsm20.ppt
 

Recently uploaded

XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsMehedi Hasan Shohan
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 

Recently uploaded (20)

XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software Solutions
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 

Evolution and Examples of Java Features, from Java 1.7 to Java 22

  • 1. Yann-Gaël Guéhéneuc (/jan/, he/il) Work licensed under Creative Commons BY-NC-SA 4.0 International New Java yann-gael.gueheneuc@concordia.ca Version 0.22.1 2024/03/28
  • 2. 2/360 Patrick Naughton Scott McNealy Mike Sheridan James Gosling 1991
  • 4. 4/360 Naming  Java – 1995/05/23 – Language  JDK (Java Development Kit) – Compiler (Java Language Specification) – VM (Java Virtual Machine Specification) – APIs/Libraries (Java Class Libraries)
  • 5. 5/360 Process  JCP: Java Community Process – Established in 1998 – JSR-387 describes JCP v2.11
  • 6. 6/360 Documents  JLSs: Java Language Specifications – What is Java  JSRs: Java Specification Requests – Parts of the JCP – New specifications and technologies – JDK/OpenJDK  JEPs: Java Enhancement Proposals – Experimental ideas – Could become JSRs https://stackoverflow.com/questions/51282326/what-is-the-difference-or-relation-between-jls-jsr-and-jep
  • 9. 9/360 Organisation  Per release – With some cross-references  Three categories – Language – JVM – APIs Misc +
  • 12. 12/360 Enums  Special data type – Declares/defines variables set to constants interface PseudoEnum0 { int YES = 0; int NO = 1; } interface Interface1 { public boolean foo(); } enum RealEnum1 implements Interface1 { YES { public boolean foo() { return true; } }, NO { public boolean foo() { return false; } }; public boolean bar() { return this.foo(); } }
  • 13. 13/360 Enums  Based on anonymous classes System.out.println(RealEnum1.YES.bar()); System.out.println(RealEnum1.NO.bar()); System.out.print("Superclass: "); System.out.println(RealEnum1.NO.getClass().getSuperclass()); System.out.print("Class: "); System.out.println(RealEnum1.NO.getClass()); for (final Method method : RealEnum1.NO.getClass().getDeclaredMethods()) { System.out.print("tMethods: "); System.out.println(method); }
  • 14. 14/360 Enums  Based on anonymous classes System.out.println(RealEnum1.YES.bar()); System.out.println(RealEnum1.NO.bar()); System.out.print("Superclass: "); System.out.println(RealEnum1.NO.getClass().getSuperclass()); System.out.print("Class: "); System.out.println(RealEnum1.NO.getClass()); for (final Method method : RealEnum1.NO.getClass().getDeclaredMethods()) { System.out.print("tMethods: "); System.out.println(method); } true false Superclass: class net.ptidej.newjava.enums.RealEnum1 Class: class net.ptidej.newjava.enums.RealEnum1$2 Methods: public boolean net.ptidej.newjava.enums.RealEnum1$2.foo()
  • 15. 15/360 Enums Enum Simulated Enum interface Interface1 { public boolean foo(); } enum RealEnum1 implements Interface1 { YES { public boolean foo() { return true; } }, NO { public boolean foo() { return false; } }; public boolean bar() { return this.foo(); } } interface Interface1 { public boolean foo(); } abstract class SimulatedEnum1 implements Interface1 { public static final SimulatedEnum1 YES = new SimulatedEnum1() { @Override public boolean foo() { return true; } }; public static final SimulatedEnum1 NO = new SimulatedEnum1() { @Override public boolean foo() { return false; } }; private SimulatedEnum1() { } public boolean bar() { return this.foo(); } }
  • 16. 16/360 Enums Enum Simulated Enum interface Interface1 { public boolean foo(); } enum RealEnum1 implements Interface1 { YES { public boolean foo() { return true; } }, NO { public boolean foo() { return false; } }; public boolean bar() { return this.foo(); } } interface Interface1 { public boolean foo(); } abstract class SimulatedEnum1 implements Interface1 { public static final SimulatedEnum1 YES = new SimulatedEnum1() { @Override public boolean foo() { return true; } }; public static final SimulatedEnum1 NO = new SimulatedEnum1() { @Override public boolean foo() { return false; } }; private SimulatedEnum1() { } public boolean bar() { return this.foo(); } } Instances of two anonymous classes
  • 17. 17/360 Enums Enum Simulated Enum interface Interface1 { public boolean foo(); } enum RealEnum1 implements Interface1 { YES { public boolean foo() { return true; } }, NO { public boolean foo() { return false; } }; public boolean bar() { return this.foo(); } } Why private? interface Interface1 { public boolean foo(); } abstract class SimulatedEnum1 implements Interface1 { public static final SimulatedEnum1 YES = new SimulatedEnum1() { @Override public boolean foo() { return true; } }; public static final SimulatedEnum1 NO = new SimulatedEnum1() { @Override public boolean foo() { return false; } }; private SimulatedEnum1() { } public boolean bar() { return this.foo(); } } Instances of two anonymous classes
  • 18. 18/360 Enums  More than just syntactic sugar – Constants are constant expressions final RealEnum3 v = // ... switch (v) { case YES: System.out.println("YES"); break; case NO: System.out.println("NO"); break; default: throw // ... } final SimulatedEnum3 v1 = // ... switch (v1) { case SimulatedEnum3.YES: System.out.println("YES"); break; case SimulatedEnum3.NO: System.out.println("NO"); break; default: throw // ... }
  • 19. 19/360 Enums  More than just syntactic sugar – Constants are constant expressions final RealEnum3 v = // ... switch (v) { case YES: System.out.println("YES"); break; case NO: System.out.println("NO"); break; default: throw // ... } final SimulatedEnum3 v1 = // ... switch (v1) { case SimulatedEnum3.YES: System.out.println("YES"); break; case SimulatedEnum3.NO: System.out.println("NO"); break; default: throw // ... } case expressions must be constant expressions
  • 20. 20/360 Enums  No work around the compilation error – Some constants are not constant expressions final SimulatedEnum3 v1 = // ... switch (v1) { case SimulatedEnum3.YES: System.out.println("YES"); break; case SimulatedEnum3.NO: System.out.println("NO"); break; default: throw // ... } final int v2 = // ... switch (v2) { case SimulatedEnum3.YES.constantID: System.out.println("YES"); break; case SimulatedEnum3.NO.constantID: System.out.println("NO"); break; default: throw // ... } public final int constantID;
  • 23. 23/360 Strings in switch https://www.baeldung.com/java-switch public String exampleOfSwitch(String animal) { String result; switch (animal) { case "DOG" : result = "domestic animal"; break; case "CAT" : result = "domestic animal"; break; case "TIGER" : result = "wild animal"; break; default : result = "unknown animal"; break; } return result; }
  • 24. 24/360 try With Resources  New interfaces – java.lang.Closeable – java.lang.AutoCloseable https://www.baeldung.com/java-try-with-resources try (final Scanner scanner = new Scanner(new File("test.txt"))) { while (scanner.hasNext()) { System.out.println(scanner.nextLine()); } } catch (final FileNotFoundException fnfe) { fnfe.printStackTrace(); }
  • 25. 25/360 Diamond Operator <> https://www.baeldung.com/java-diamond-operator List<String> cars = new ArrayList<String>(); List<String> cars = new ArrayList<>(); vs.
  • 26. 26/360 Vargs in Method Declaration https://www.baeldung.com/java-varargs https://www.baeldung.com/java-varargs public String format() { // ... } public String format(String value) { //... } public String format(String val1, String val2) { // ... } public String formatWithVarArgs(String... values) { System.out.println(values[0]); System.out.println(values[1]); System.out.println(values[3]); // ... } vs.
  • 27. 27/360 Binary Integer Literals https://www.geeksforgeeks.org/java-program-to-illustrate-use-of-binary-literals/ // Byte type Binary Literal byte a1 = 0b011; // Short type Binary Literal short b1 = 0b101; // Int type Binary literal int c1 = 0b011; // Long type Binary literal long d1 = 0b0000011111100011;
  • 28. 28/360 Underscores in Numeric Literals int i = 12_34_56; System.out.println(i); https://www.geeksforgeeks.org/using-underscore-numeric-literals-java/
  • 29. 29/360 Multiple Exception Types  Multiple exception types  Multiple exceptions rethrown with improved type checking
  • 30. 30/360 Multiple Exception Types public static void main(final String[] args) { try { Example1.rethrow("abc"); } catch (final FirstException | SecondException e) { // Below assignment would throw a compile-time exception, e is implicitly final // e = new Exception(); System.out.println(e.getMessage()); } } private static void rethrow(final String s) throws FirstException, SecondException { try { if (s.equals("First")) throw new FirstException("First"); else throw new SecondException("Second"); } catch (final Exception e) { // Below assignment would disable improved rethrow exception type checking // e = new ThirdException(); throw e; } } private static class FirstException extends Exception { public FirstException(String msg) { super(msg); } } // ...
  • 32. 32/360 JSR-292: invokedynamic  invokestatic, for class methods  invokevirtual, for instance methods  invokeinterface, for interface methods  invokespecial, for instance initialisation, superclass, and private methods
  • 34. 34/360 JSR-292: invokedynamic  invokedynamic indicates that a dynamic language run-time specific call occurs  The call occurs through MethodHandle(s) https://www.baeldung.com/java-method-handles MethodHandles.Lookup publicLookup = MethodHandles.publicLookup(); MethodType mt = MethodType.methodType(String.class, char.class, char.class); MethodHandle replaceMH = publicLookup.findVirtual(String.class, "replace", mt); String output = (String) replaceMH.invoke("jovo", 'o', 'a');
  • 36. 36/360 JSR-166: Concurrency Utilities  Concurrency utilities under JSR 166  java.util.concurrent wants to be for concurrency what java.util.Collections is for collections  With some JVM support – Timing – Atomics – … https://gee.cs.oswego.edu/dl/concurrency-interest/jsr166-slides.pdf
  • 40. 40/360 JSR-166: Concurrency Utilities https://gee.cs.oswego.edu/dl/concurrency-interest/jsr166-slides.pdf final Runnable runnable1 = new RunnableExample("executor.execute(...)"); final ExecutorService executor = Executors.newFixedThreadPool(10); executor.execute(runnable1); final Runnable runnable2 = new RunnableExample("new Thread(...)"); new Thread(runnable2).start(); vs.
  • 41. 41/360 JSR-166: Concurrency Utilities class ImageRenderer { Image render(final byte[] raw) { return // ... } } public class Example2 { public void display(final byte[] raw) throws InterruptedException, ExecutionException { final ExecutorService executor = Executors.newFixedThreadPool(10); final ImageRenderer renderer = new ImageRenderer(); final Future<Image> image = executor.submit(new Callable<Image>() { public Image call() { return renderer.render(raw); } }); drawBorders(); // do other things ... drawCaption(); // ... while executing drawImage(image.get()); // use Future } // ... https://gee.cs.oswego.edu/dl/concurrency-interest/jsr166-slides.pdf
  • 42. 42/360 JSR-166: Concurrency Utilities public void run() { synchronized (this.resource) { this.resource.doSomething(); } this.resource.doLogging(); } public void run() { try { if (this. lock.tryLock(10, TimeUnit.SECONDS)) { this.resource.doSomething(); } } catch (final InterruptedException exception) { exception.printStackTrace(); } finally { this.lock.unlock(); } this.resource.doLogging(); } vs. https://www.digitalocean.com/com munity/tutorials/java-lock-example- reentrantlock
  • 43. 43/360 JSR-166: Concurrency Utilities https://www.geeksforgeeks.org/semaphore-in-java/ private final Semaphore semaphore; private void connect(final String user) throws InterruptedException { System.out.println(getCurrentDateTime() + " : " + user + " waiting sem"); this.semaphore.acquire(); System.out.println(getCurrentDateTime() + " : " + user + " acquired sem"); Thread.sleep(1000); // Some work... this.semaphore.release(); System.out.println(getCurrentDateTime() + " : " + user + " released sem"); } https://mkyong.com/java/java-semaphore-examples/
  • 44. 44/360 JSR-166: Concurrency Utilities https://www.geeksforgeeks.org/atomic-variables-in-java-with-examples/ class Counter extends Thread { private final AtomicInteger count; public Counter() { this.count = new AtomicInteger(); } public void run() { final int max = 10_000_000; for (int i = 0; i < max; i++) { count.addAndGet(1); } } public int getCount() { return this.count.get(); } }
  • 45. 45/360 JSR-203: New File I/O Library  Extensive File I/O API  Socket channel API  Asynchronous I/O API
  • 46. 46/360 JSR-203: New File I/O Library  Extensive File I/O API https://www.baeldung.com/java-nio2-file-visitor https://www.baeldung.com/java-nio2-file-visitor public class Example1FileVisitor { public static void main(final String[] args) throws IOException { final Path startPath = Paths.get("D:DocumentsTutorials220926 - New Java"); final String fileName = "Example1FileVisitor.java"; final FileVisitorImpl visitor = new FileVisitorImpl(fileName, startPath); Files.walkFileTree(startPath, visitor); } }
  • 47. 47/360 JSR-203: New File I/O Library https://www.baeldung.com/java-nio2-file-visitor class FileVisitorImpl implements FileVisitor<Path> { private final String fileName; private final Path startPath; public FileVisitorImpl(final String aFileName, final Path aStartPath) { this.fileName = aFileName; this.startPath = aStartPath; } @Override public FileVisitResult preVisitDirectory(final Path aPath, final BasicFileAttributes someAttributes) { return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(final Path aPath, final BasicFileAttributes someAttributes) { final String fileName = aPath.getFileName().toString(); if (fileName.equals(this.fileName)) { return FileVisitResult.TERMINATE; } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(final Path aPath, final IOException anIOException) { return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(final Path aPath, final IOException anIOException) { try { if (Files.isSameFile(aPath, this.startPath)) { return FileVisitResult.TERMINATE; } } catch (final IOException e) { e.printStackTrace(); } return FileVisitResult.CONTINUE; } }
  • 48. 48/360 JSR-203: New File I/O Library  Socket channel API – Client public static void client() throws IOException { final ServerSocketChannel serverSocket = ServerSocketChannel.open(); serverSocket.socket().bind(new InetSocketAddress(9000)); final SocketChannel client = serverSocket.accept(); System.out.println("Connection set: " + client.getRemoteAddress()); final Path path = Paths.get("D:DocumentsTutorials220926 - New JavaReceivedFile.txt"); final FileChannel fileChannel = FileChannel.open( path, EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)); final ByteBuffer buffer = ByteBuffer.allocate(1024); while (client.read(buffer) > 0) { buffer.flip(); fileChannel.write(buffer); buffer.clear(); } fileChannel.close(); System.out.println("File received"); client.close(); } https://www.tutorialspoint.com/java_nio/java_nio_socket_channel.htm
  • 49. 49/360 JSR-203: New File I/O Library  Socket channel API – Server https://www.tutorialspoint.com/java_nio/java_nio_socket_channel.htm public static void server() throws IOException { final SocketChannel server = SocketChannel.open(); final SocketAddress socketAddr = new InetSocketAddress("localhost", 9000); server.connect(socketAddr); final Path path = Paths.get("D:DocumentsTutorials220926 - New JavaPatterns.txt"); final FileChannel fileChannel = FileChannel.open(path); final ByteBuffer buffer = ByteBuffer.allocate(1024); while (fileChannel.read(buffer) > 0) { buffer.flip(); server.write(buffer); buffer.clear(); } fileChannel.close(); System.out.println("File sent"); server.close(); }
  • 50. 50/360 JSR-203: New File I/O Library  Socket channel API – Main public static void main(final String[] args) { final Runnable runnableClient = new Runnable() { public void run() { try { Example2SocketChannel.client(); } catch (final IOException e) { } } }; final Runnable runnableServer = new Runnable() { public void run() { try { Example2SocketChannel.server(); } catch (final IOException e) { } } }; final ExecutorService executor = Executors.newFixedThreadPool(2); executor.execute(runnableClient); executor.execute(runnableServer); } https://www.tutorialspoint.com/java_nio/java_nio_socket_channel.htm
  • 51. 51/360 JSR-203: New File I/O Library  Asynchronous I/O API “The asynchronous channel APIs were introduced into the existing java.nio.channels package […] by prefixing […] with Asynchronous”
  • 52. 52/360 Translucent and Shaped Windows  Improves Java Swing  Allow new, nicer themes https://ateraimemo.com/Swing/TranslucentFrame.html Window.setShape(Shape s) Window.setOpacity(float f)
  • 53. 53/360 Network Protocols  Network protocols – Stream Control Transport Protocol (SCTP) – Sockets Direct Protocol (SDP)  In packages – com.sun.nio.sctp – com.sun.sdp https://www.oracle.com/technical-resources/articles/javase/sctp.html final SctpServerChannel ssc = SctpServerChannel.open(); final InetSocketAddress serverAddr = // ... ssc.bind(serverAddr); while (true) { final SctpChannel sc = ssc.accept(); final Date today = new Date(); cbuf.put(USformatter.format(today)).flip(); encoder.encode(cbuf, buf, true); buf.flip(); messageInfo.streamNumber(FUS_STREAM); sc.send(buf, messageInfo); buf.clear(); cbuf.clear(); cbuf.put(FRformatter.format(today)).flip(); encoder.encode(cbuf, buf, true); buf.flip(); messageInfo.streamNumber(FR_STREAM); sc.send(buf, messageInfo); buf.clear(); cbuf.clear(); // ...
  • 54. 54/360 Updates to XML and Unicode  New system property named org.jcp.xml.dsig.secureValidation  New XML Processing Limits  Regular Expression pattern matching supports Unicode 6.0.0 – Major version of the Unicode Standard
  • 57. 57/360 default, static Interface Methods public interface IA { int foo(); default int bar() { return 42; } } public static void main(final String[] args) { final IA anIA = new IA() { public int foo() { return 0; } }; System.out.println(anIA.foo()); System.out.println(anIA.bar()); final IA anotherIA = new IA() { public int foo() { return IA.super.bar(); } public int bar() { return 0; } }; System.out.println(anotherIA.foo()); System.out.println(anotherIA.bar()); }
  • 58. 58/360 default, static Interface Methods public interface IA { int foo(); default int bar() { return 42; } } public static void main(final String[] args) { final IA anIA = new IA() { public int foo() { return 0; } }; System.out.println(anIA.foo()); System.out.println(anIA.bar()); final IA anotherIA = new IA() { public int foo() { return IA.super.bar(); } public int bar() { return 0; } }; System.out.println(anotherIA.foo()); System.out.println(anotherIA.bar()); } 0 42 42 0
  • 59. 59/360 default, static Interface Methods  https://stackoverflow.c om/questions/512877/ why-cant-i-define-a- static-method-in-a- java-interface public interface IA { int foo(); static int bar() { return 42; } } public class A { int foo() { return 0; } static int bar() { return 42; } } public static void main(final String[] args) { final IA anIA = new IA() { public int foo() { return 0; } }; System.out.println(anIA.foo()); System.out.println(anIA.bar()); final A anA = new A(); System.out.println(anA.foo()); System.out.println(anA.bar()); }
  • 60. 60/360 default, static Interface Methods  https://stackoverflow.c om/questions/512877/ why-cant-i-define-a- static-method-in-a- java-interface public interface IA { int foo(); static int bar() { return 42; } } public class A { int foo() { return 0; } static int bar() { return 42; } } public static void main(final String[] args) { final IA anIA = new IA() { public int foo() { return 0; } }; System.out.println(anIA.foo()); System.out.println(anIA.bar()); final A anA = new A(); System.out.println(anA.foo()); System.out.println(anA.bar()); }
  • 61. 61/360 default, static Interface Methods  https://stackoverflow.c om/questions/512877/ why-cant-i-define-a- static-method-in-a- java-interface public interface IA { int foo(); static int bar() { return 42; } } public class A { int foo() { return 0; } static int bar() { return 42; } } public static void main(final String[] args) { final IA anIA = new IA() { public int foo() { return 0; } }; System.out.println(anIA.foo()); System.out.println(anIA.bar()); final A anA = new A(); System.out.println(anA.foo()); System.out.println(anA.bar()); } System.out.println(IA.bar());
  • 62. 62/360 JSR-335, JEP-126: λ Expressions  λ Expressions interface Applicable<T, R> { public R apply(final T aParameter); } public static void main(final String[] args) { final Applicable<String, Integer> strlen = new Applicable<>() { @Override public Integer apply(final String aParameter) { return aParameter.length(); } }; System.out.println(strlen.apply("Hello, World!")); } https://jenkov.com/tutorials/java-functional-programming/functional-interfaces.html
  • 63. 63/360 JSR-335, JEP-126: λ Expressions    interface Applicable<T, R> { public R apply(final T aParameter); } public static void main(final String[] args) { final Applicable<String, Integer> strlen = new Applicable<>() { @Override public Integer apply(final String aParameter) { return aParameter.length(); } }; System.out.println(strlen.apply("Hello, World!")); }
  • 64. 64/360 JSR-335, JEP-126: λ Expressions  Lots of boilerplate code  Difficult to understand  Not common in the libraries interface Applicable<T, R> { public R apply(final T aParameter); } public static void main(final String[] args) { final Applicable<String, Integer> strlen = new Applicable<>() { @Override public Integer apply(final String aParameter) { return aParameter.length(); } }; System.out.println(strlen.apply("Hello, World!")); }
  • 65. 65/360 JSR-335, JEP-126: λ Expressions  Solution – Simple syntactic sugar – Set of functional interfaces – Libraries using these interfaces
  • 66. 66/360 JSR-335, JEP-126: λ Expressions  Solution – Simple syntactic sugar – Set of functional interfaces – Libraries using these interfaces
  • 67. 67/360 JSR-335, JEP-126: λ Expressions  Solution – Simple syntactic sugar – Set of functional interfaces – Libraries using these interfaces interface Applicable<T, R> { public R apply(final T aParameter); } public static void main(final String[] args) { final Applicable<String, Integer> strlen = (paramter) -> paramter.length(); System.out.println(strlen.apply("Hello, World!")); }
  • 68. 68/360 JSR-335, JEP-126: λ Expressions  Solution – Simple syntactic sugar – Set of functional interfaces – Libraries using these interfaces interface Applicable<T, R> { public R apply(final T aParameter); } public static void main(final String[] args) { final Applicable<String, Integer> strlen = (paramter) -> paramter.length(); System.out.println(strlen.apply("Hello, World!")); } public static void main(final String[] args) { final Applicable<String, Integer> strlen = String::length; System.out.println(strlen.apply("Hello, World!")); }
  • 69. 69/360 JSR-335, JEP-126: λ Expressions  Solution – Simple syntactic sugar – Set of functional interfaces – Libraries using these interfaces http://blog.orfjackal.net/2014/07/java-8-functional-interface-naming-guide.html
  • 70. 70/360 JSR-335, JEP-126: λ Expressions  Solution – Simple syntactic sugar – Set of functional interfaces – Libraries using these interfaces http://blog.orfjackal.net/2014/07/java-8-functional-interface-naming-guide.html
  • 71. 71/360 JSR-335, JEP-126: λ Expressions  Solution – Simple syntactic sugar – Set of functional interfaces – Libraries using these interfaces https://blogs.oracle.com/javamagazine/post/functional-programming-in-java-part-1-lists-lambdas-and-method-references
  • 72. 72/360 JSR-335, JEP-126: λ Expressions  Solution – Simple syntactic sugar – Set of functional interfaces – Libraries using these interfaces https://blogs.oracle.com/javamagazine/post/functional-programming-in-java-part-1-lists-lambdas-and-method-references final List<String> friends = Arrays.asList("Rick Deckard", "Roy Batty", "Harry Bryant", "Hannibal Chew", "Gaff", "Holden", "Leon Kowalski", "Taffey Lewis", "Pris", "Rachael", "J.F. Sebastian", "Dr. Eldon Tyrell", "Zhora", "Hodge", "Mary"); for (int i = 0; i < friends.size(); i++) { System.out.println(friends.get(i)); } for (String name : friends) { System.out.println(name); } friends.forEach(new Consumer<String>() { public void accept(final String aName) { System.out.println(aName); }}); friends.forEach((final String name) -> System.out.println(name)); friends.forEach((name) -> System.out.println(name)); friends.forEach(name -> System.out.println(name)); friends.forEach(System.out::println); friends.stream().map(String::toUpperCase).forEach( name -> System.out.print(name + " ")); System.out.println(); final List<String> namesStartingWithN = friends.stream(). filter(name -> name.startsWith("R")).collect(Collectors.toList()); System.out.println(namesStartingWithN);
  • 73. 73/360 JSR-335, JEP-126: λ Expressions  But code duplication! https://blogs.oracle.com/javamagazine/post/functional-programming- in-java-part-2-lambda-reuse-lexical-scoping-and-closures-and-reduce output = friends1.stream().filter(name -> name.startsWith("R")).collect(Collectors.toList()); System.out.println(output); output = friends2.stream().filter(name -> name.startsWith("R")).collect(Collectors.toList()); System.out.println(output); final Predicate<String> predicate = name -> name.startsWith("R"); output = friends1.stream().filter(predicate).collect(Collectors.toList()); System.out.println(output); output = friends2.stream().filter(predicate).collect(Collectors.toList()); System.out.println(output); vs.
  • 74. 74/360 JSR-335, JEP-126: λ Expressions  But code duplication! https://blogs.oracle.com/javamagazine/post/functional-programming- in-java-part-2-lambda-reuse-lexical-scoping-and-closures-and-reduce // Lexical scoping and closure output = friends1.stream().filter(checkIfStartsWith("R")).collect(Collectors.toList()); System.out.println(output); output = friends2.stream().filter(checkIfStartsWith("P")).collect(Collectors.toList()); System.out.println(output); // Narrower lexical scoping final Function<String, Predicate<String>> startsWithLetter = letter -> (name -> name.startsWith(letter)); output = friends1.stream().filter(startsWithLetter.apply("R")).collect(Collectors.toList()); System.out.println(output); output = friends2.stream().filter(startsWithLetter.apply("P")).collect(Collectors.toList()); System.out.println(output); vs.
  • 75. 75/360 JSR-335, JEP-126: λ Expressions  But code duplication! https://blogs.oracle.com/javamagazine/post/functional-programming- in-java-part-2-lambda-reuse-lexical-scoping-and-closures-and-reduce // Lexical scoping and closure output = friends1.stream().filter(checkIfStartsWith("R")).collect(Collectors.toList()); System.out.println(output); output = friends2.stream().filter(checkIfStartsWith("P")).collect(Collectors.toList()); System.out.println(output); // Narrower lexical scoping final Function<String, Predicate<String>> startsWithLetter = letter -> (name -> name.startsWith(letter)); output = friends1.stream().filter(startsWithLetter("R")).collect(Collectors.toList()); System.out.println(output); output = friends2.stream().filter(startsWithLetter("P")).collect(Collectors.toList()); System.out.println(output); vs.
  • 76. 76/360 JSR-335, JEP-126: λ Expressions  But code duplication! https://forum.devtalk.com/t/functional-programming-in-java-second- edition-p-35-refactoring-to-narrow-the-scope-code/105447 // Lexical scoping and closure output = friends1.stream().filter(checkIfStartsWith("R")).collect(Collectors.toList()); System.out.println(output); output = friends2.stream().filter(checkIfStartsWith("P")).collect(Collectors.toList()); System.out.println(output); // Narrower lexical scoping final Function<String, Predicate<String>> startsWithLetter = letter -> (name -> name.startsWith(letter)); output = friends1.stream().filter(startsWithLetter("R")).collect(Collectors.toList()); System.out.println(output); output = friends2.stream().filter(startsWithLetter("P")).collect(Collectors.toList()); System.out.println(output); vs.
  • 77. 77/360 JSR-308, JEP-104: Type Annotations  Allow pluggable type systems  Help enforce stronger typing public class Example1 { public static void main(final String[] args) { final String aString = null; final String anotherString = aString; System.out.println(anotherString); } }
  • 78. 78/360 JSR-308, JEP-104: Type Annotations  Allow pluggable type systems  Help enforce stronger typing public class Example1 { public static void main(final String[] args) { final String aString = null; final String anotherString = aString; System.out.println(anotherString); } } public class Example1 { public static void main(final String[] args) { final String aString = null; final @NonNull String anotherString = aString; System.out.println(anotherString); } }
  • 79. 79/360 JSR-308, JEP-104: Type Annotations  Allow pluggable type systems  Help enforce stronger typing public class Example1 { public static void main(final String[] args) { final String aString = null; final String anotherString = aString; System.out.println(anotherString); } } public class Example1 { public static void main(final String[] args) { final String aString = null; final @NonNull String anotherString = aString; System.out.println(anotherString); } } Null type mismatch: required '@NonNull String' but the provided value is null
  • 80. 80/360 JSR-308, JEP-104: Type Annotations  Allow pluggable type systems  Help enforce stronger typing public class Example1 { public static void main(final String[] args) { final String aString = null; final String anotherString = aString; System.out.println(anotherString); } } public class Example1 { public static void main(final String[] args) { final String aString = null; final @NonNull String anotherString = aString; System.out.println(anotherString); } } public class Example1 { public static void main(final String[] args) { final String aString = ""; final @NonNull String anotherString = aString; System.out.println(anotherString); } } Null type mismatch: required '@NonNull String' but the provided value is null
  • 81. 81/360 JSR-308, JEP-104: Type Annotations class A { String getString() { return null; } } public class Example2 { public static void foo1() { final A a = new A(); final String aString = a.getString(); final @NonNull String anotherString = aString; System.out.println(anotherString); } public static void foo2() { final A a = new A(); final String aString = a.getString(); if (aString != null) { final @NonNull String anotherString = aString; System.out.println(anotherString); } } }
  • 82. 82/360 JSR-308, JEP-104: Type Annotations class A { String getString() { return null; } } public class Example2 { public static void foo1() { final A a = new A(); final String aString = a.getString(); final @NonNull String anotherString = aString; System.out.println(anotherString); } public static void foo2() { final A a = new A(); final String aString = a.getString(); if (aString != null) { final @NonNull String anotherString = aString; System.out.println(anotherString); } } } Null type safety […] needs unchecked conversion to conform to '@NonNull String'
  • 83. 83/360 JSR-308, JEP-104: Type Annotations  “The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.” – https://checkerframework.org/tutorial/
  • 84. 84/360 Unsigned Integer Arithmetic  Comparison  Division/Modulo  Parsing  Formatting https://www.baeldung.com/java-unsigned-arithmetic public class Example1 { public static void main(String[] args) { final int positive = Integer.MAX_VALUE; final int negative = Integer.MIN_VALUE; final int signedComparison = Integer.compare(positive, negative); if (signedComparison > 0) { System.out.println("Positive > negative (signed comparison)"); } final int unsignedComparison = Integer.compareUnsigned(positive, negative); if (unsignedComparison < 0) { System.out.println("Positive NOT > negative (unsigned comparison)"); } } }
  • 85. 85/360 JEP-120: Repeating Annotations  “Annotations, a form of metadata, provide data about a program that is not part of the program [and] have no direct effect on the operation of the code they annotate.” https://docs.oracle.com/javase/tutorial/java/annotations/
  • 86. 86/360 JEP-120: Repeating Annotations  “Annotations, a form of metadata, provide data about a program that is not part of the program [and] have no direct effect on the operation of the code they annotate.” https://docs.oracle.com/javase/tutorial/java/annotations/
  • 87. 87/360 JEP-120: Repeating Annotations https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99 @Retention(RetentionPolicy.RUNTIME) @interface ScheduleNonRepeatable1 { String dayOfMonth() default "First"; String dayOfWeek() default "Mon"; int hour() default 12; } @ScheduleNonRepeatable1(dayOfWeek = "Fri", hour = 23) public class Example1 { public static void main(final String[] args) { final Example1 example1 = new Example1(); final Annotation annotation = example1.getClass(). getAnnotation(ScheduleNonRepeatable1.class); System.out.println(annotation); } }
  • 88. 88/360 JEP-120: Repeating Annotations https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99 @Retention(RetentionPolicy.RUNTIME) @interface ScheduleNonRepeatable1 { String dayOfMonth() default "First"; String dayOfWeek() default "Mon"; int hour() default 12; } @ScheduleNonRepeatable1(dayOfWeek = "Fri", hour = 23) public class Example1 { public static void main(final String[] args) { final Example1 example1 = new Example1(); final Annotation annotation = example1.getClass(). getAnnotation(ScheduleNonRepeatable1.class); System.out.println(annotation); } } @ScheduleNonRepeatable1(hour=23, dayOfMonth="First", dayOfWeek="Fri")
  • 89. 89/360 JEP-120: Repeating Annotations https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99 @Retention(RetentionPolicy.RUNTIME) @interface ScheduleNonRepeatable2 { String dayOfMonth() default "First"; String dayOfWeek() default "Mon"; int hour() default 12; } @ScheduleNonRepeatable2(dayOfMonth = "last") @ScheduleNonRepeatable2(dayOfWeek = "Fri", hour = 23) public class Example2 { public static void main(final String[] args) { final Example2 example2 = new Example2(); final Annotation annotation = example2.getClass(). getAnnotation(ScheduleNonRepeatable2.class); System.out.println(annotation); } }
  • 90. 90/360 JEP-120: Repeating Annotations https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99 @Retention(RetentionPolicy.RUNTIME) @interface ScheduleNonRepeatable2 { String dayOfMonth() default "First"; String dayOfWeek() default "Mon"; int hour() default 12; } @ScheduleNonRepeatable2(dayOfMonth = "last") @ScheduleNonRepeatable2(dayOfWeek = "Fri", hour = 23) public class Example2 { public static void main(final String[] args) { final Example2 example2 = new Example2(); final Annotation annotation = example2.getClass(). getAnnotation(ScheduleNonRepeatable2.class); System.out.println(annotation); } } Duplicate annotation of non-repeatable type @ScheduleNonRepeatable2
  • 91. 91/360 JEP-120: Repeating Annotations https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99 @Retention(RetentionPolicy.RUNTIME) @interface Schedules { ScheduleRepeatable[] value(); } @Retention(RetentionPolicy.RUNTIME) @Repeatable(Schedules.class) @interface ScheduleRepeatable { String dayOfMonth() default "First"; String dayOfWeek() default "Mon"; int hour() default 12; } @ScheduleRepeatable(dayOfMonth = "last") @ScheduleRepeatable(dayOfWeek = "Fri", hour = 23) public class Example3 { public static void main(final String[] args) { final Example3 example3 = new Example3(); final Annotation annotation = example3.getClass(). getAnnotation(Schedules.class); System.out.println(annotation); } }
  • 92. 92/360 JEP-120: Repeating Annotations https://rolyhewage.medium.com/type-annotations-repeating-annotations-in-java-722073df9f99 @Retention(RetentionPolicy.RUNTIME) @interface Schedules { ScheduleRepeatable[] value(); } @Retention(RetentionPolicy.RUNTIME) @Repeatable(Schedules.class) @interface ScheduleRepeatable { String dayOfMonth() default "First"; String dayOfWeek() default "Mon"; int hour() default 12; } @ScheduleRepeatable(dayOfMonth = "last") @ScheduleRepeatable(dayOfWeek = "Fri", hour = 23) public class Example3 { public static void main(final String[] args) { final Example3 example3 = new Example3(); final Annotation annotation = example3.getClass(). getAnnotation(Schedules.class); System.out.println(annotation); } } @Schedules({@ScheduleRepeatable(hour=12, dayOfMonth="last", dayOfWeek="Mon"), @ScheduleRepeatable(hour=23, dayOfMonth="First", dayOfWeek="Fri")})
  • 94. 94/360 JEP-178: Statically-linked JNI Libraries  Native programs that embed the JRE  Java programs running in environments without shared libraries  Enable developers to package a Java run- time, native code, and Java code together into a single binary
  • 95. 95/360 JEP-122: Permanent Generation Removal  “Automatic garbage collection is [..] identifying which objects are in use and […] deleting the unused objects.”  Remove Permanent Generation – No more size tuning https://openjdk.org/jeps/122
  • 97. 97/360 JEP-174: Nashorn JS Engine  Successor of Mozilla’s Rhino  100% in ECMAScript v5.1 test suite  Java 8: Introduced  Java 11: Deprecated  Java 15: Removed
  • 98. 98/360 JEP-174: Nashorn JS Engine  https://github.com/openjdk/nashorn https://www.baeldung.com/java-nashorn final ScriptEngine engine = new ScriptEngineManager().getEngineByName("Nashorn"); final Bindings bindings = engine.createBindings(); bindings.put("name", "Nashorn"); result = engine.eval("var greeting = 'hello world' + name;" + "print(greeting);" + "greeting"); System.out.println(result); final Invocable invocable = (Invocable) engine; engine.eval("function composeGreeting(name) {" + "return 'Hello ' + name" + "}"); result = invocable.invokeFunction("composeGreeting", "Nashorn"); System.out.println(result); result = engine.eval("var HashMap = Java.type('java.util.HashMap’);" + "var map = new HashMap();" + "map.put('hello', 'world');" + "map"); System.out.println(result);
  • 99. 99/360 JSR-310, JEP-150: Date, Time API  Need to manipulate dates and times  Disparate APIs, missing features – Set time to midnight for a date without a time  Complete terminology  Complete, cohesive implementation – java.time.*
  • 101. 101/360 JEP-153: JavaFX Applications  Three “types” of programs – Class files – JAR files – JavaFX  Enhance the java command-line to launch JavaFX programs
  • 104. 104/360 Private Interface Methods public interface IA { int foo(); default int bar() { return this.bar1(); } private int bar1() { return 42; } } public static void main(final String[] args) { final IA anIA = new IA() { public int foo() { return 0; } }; System.out.println(anIA.foo()); System.out.println(anIA.bar()); final IA anotherIA = new IA() { public int foo() { return IA.super.bar1(); } public int bar() { return 0; } }; System.out.println(anotherIA.foo()); System.out.println(anotherIA.bar()); }
  • 105. 105/360 Private Interface Methods public interface IA { int foo(); default int bar() { return this.bar1(); } private int bar1() { return 42; } } public static void main(final String[] args) { final IA anIA = new IA() { public int foo() { return 0; } }; System.out.println(anIA.foo()); System.out.println(anIA.bar()); final IA anotherIA = new IA() { public int foo() { return IA.super.bar1(); } public int bar() { return 0; } }; System.out.println(anotherIA.foo()); System.out.println(anotherIA.bar()); } 0 42 42 0
  • 106. 106/360 JSR-376: Modularization  JSR-376: Java Platform Module System, part of Project Jigsaw – Ease library construction, maintenance – Security, maintainability of Java (and JDK) – Allow scaling down programs for small devices – Improve program compilation and loading times https://openjdk.org/projects/jigsaw/
  • 107. 107/360 JSR-376: Modularization  JEP-200: The Modular JDK  JEP-201: Modular Source Code  JEP-220: Modular Run-time Images  JEP-260: Encapsulate Most Internal APIs  JEP-261: Module System  JEP-282: jlink: The Java Linker  JSR 376: Java Platform Module System
  • 108. 108/360 JSR-376: Modularization  Classpath / JARs Hell  Version conflicts  Large Monolithic JDK  Security Problems https://www.geeksforgeeks.org/jpms-java-platform-module-system/
  • 109. 109/360 JSR-376: Modularization  Classpath / JARs Hell  Version conflicts – Cf. DLL Hell, no versions, one directory – One, long list of JAR files • Run-time missing dependencies • Order of declaration (shadowing)  Large Monolithic JDK  Security Problems https://www.geeksforgeeks.org/jpms-java-platform-module-system/
  • 110. 110/360 JSR-376: Modularization  Classpath / JARs Hell  Version conflicts  Large Monolithic JDK – E.g., in Java v1.4.2, RT.jar is 21.8 MB (!)  Security Problems https://www.geeksforgeeks.org/jpms-java-platform-module-system/
  • 111. 111/360 JSR-376: Modularization  Classpath / JARs Hell  Version conflicts  Large Monolithic JDK  Security Problems – Implementation classes must be public – Cannot control access to these classes – padl.kernel vs. padl.kernel.impl https://www.geeksforgeeks.org/jpms-java-platform-module-system/
  • 112. 112/360 JSR-376: Modularization  A module is a “package of packages” – With one module descriptor – With own resources (data)  A module descriptor – Domain Specific Language – exports, module, open, opens, provides, requires, to, transitive, uses, and with
  • 113. 113/360 JSR-376: Modularization Raoul-Gabriel Urma, Mario Fusco, Alan Mycroft ; Modern Java in Action ; Manning, 2018 (Chapter 14) module com.example.foo { requires transitive com.example.foo.network; requires static com.example.foo.http; requires java.logging; exports com.example.foo.bar; exports com.example.foo.internal to com.example.foo.probe; opens com.example.foo.quux; opens com.example.foo.internal to com.example.foo.network, com.example.foo.probe; uses com.example.foo.spi.Intf; provides com.example.foo.spi.Data with com.example.foo.Impl; }
  • 114. 114/360 JSR-376: Modularization Raoul-Gabriel Urma, Mario Fusco, Alan Mycroft ; Modern Java in Action ; Manning, 2018 (Chapter 14) module com.example.foo { requires transitive com.example.foo.network; requires static com.example.foo.http; requires java.logging; exports com.example.foo.bar; exports com.example.foo.internal to com.example.foo.probe; opens com.example.foo.quux; opens com.example.foo.internal to com.example.foo.network, com.example.foo.probe; uses com.example.foo.spi.Intf; provides com.example.foo.spi.Data with com.example.foo.Impl; }
  • 115. 115/360 JSR-376: Modularization  Declaration of module com.example.foo  Dependencies on three other modules – transitive: client modules also can access that module – static: at compile-time, option at run-time module com.example.foo { requires transitive com.example.foo.network; requires static com.example.foo.http; requires java.logging; exports com.example.foo.bar; exports com.example.foo.internal to com.example.foo.probe; opens com.example.foo.quux; opens com.example.foo.internal to com.example.foo.network, com.example.foo.probe; uses com.example.foo.spi.Intf; provides com.example.foo.spi.Data with com.example.foo.Impl; }
  • 116. 116/360 JSR-376: Modularization  (Qualified) exports to other, client modules – Public types accessible to all client modules – Or only to types in com.example.foo.probe module com.example.foo { requires transitive com.example.foo.network; requires static com.example.foo.http; requires java.logging; exports com.example.foo.bar; exports com.example.foo.internal to com.example.foo.probe; opens com.example.foo.quux; opens com.example.foo.internal to com.example.foo.network, com.example.foo.probe; uses com.example.foo.spi.Intf; provides com.example.foo.spi.Data with com.example.foo.Impl; }
  • 117. 117/360 JSR-376: Modularization  (Qualified) opening to other, client modules at run-time only – Public types accessible to all client modules – Or only to types in com. example.foo.network or com.example.foo.probe – Allows introspection module com.example.foo { requires transitive com.example.foo.network; requires static com.example.foo.http; requires java.logging; exports com.example.foo.bar; exports com.example.foo.internal to com.example.foo.probe; opens com.example.foo.quux; opens com.example.foo.internal to com.example.foo.network, com.example.foo.probe; uses com.example.foo.spi.Intf; provides com.example.foo.spi.Data with com.example.foo.Impl; }
  • 118. 118/360 module com.example.foo { requires transitive com.example.foo.network; requires static com.example.foo.http; requires java.logging; exports com.example.foo.bar; exports com.example.foo.internal to com.example.foo.probe; opens com.example.foo.quux; opens com.example.foo.internal to com.example.foo.network, com.example.foo.probe; uses com.example.foo.spi.Intf; provides com.example.foo.spi.Data with com.example.foo.Impl; } JSR-376: Modularization  Service consumer – Interface/abstract class com.example.foo.spi.Intf  Service provider – Interface/abstract class com.example.foo.spi.Data – With concrete class com.example.foo.Impl
  • 119. 119/360 JSR-376: Modularization  modularisation.Client – Can access any public type at compile-time and at run-time – Can access some protected/private data with introspection  internal.Client – Cannot access HiddenImplementation
  • 120. 120/360 JSR-376: Modularization  modularisation.Client – Can access any public type at compile-time and at run-time – Can access some protected/private data with introspection  internal.Client – Cannot access HiddenImplementation Package-protected Class (not public!)
  • 121. 121/360 JSR-376: Modularization final Interface aki = new Implementation(); aki.foo(); System.out.println("Call on public implementation: "); final Class<? extends Interface> implementation1 = Class .forName(“....impl.Implementation").asSubclass(Interface.class); final Interface aki1 = implementation1.getDeclaredConstructor().newInstance(); final Method[] methods1 = implementation1.getDeclaredMethods(); for (final Method method : methods1) { try { method.setAccessible(true); method.invoke(aki1, new Object[0]); } catch (final RuntimeException e) { System.out.println(e.getMessage()); } } final Class<? extends Interface> implementation2 = Class .forName(“....impl.HiddenImplementation").asSubclass(Interface.class); final Interface aki2 = implementation2.getDeclaredConstructor().newInstance(); final Method[] methods2 = implementation2.getDeclaredMethods(); for (final Method method : methods2) { // Same code
  • 122. 122/360 JSR-376: Modularization  The client code has access to the fields and methods in all public types, even if private Direct call: Implementation.bar() Call on public implementation: bar: Implementation.bar() foo: Implementation.bar() Call on hidden implementation: Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation with package access ...
  • 123. 123/360 JSR-376: Modularization  The client code has access to the fields and methods in all public types, even if private Direct call: Implementation.bar() Call on public implementation: bar: Implementation.bar() foo: Implementation.bar() Call on hidden implementation: Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation with package access ... Including the private method
  • 124. 124/360 JSR-376: Modularization  Client  Provider module ModularizationWithModulesClient1 { requires ModularizationWithModulesLibrary1; } module ModularizationWithModulesLibrary1 { exports net.ptidej.modularisation.kernel; exports net.ptidej.modularisation.kernel.impl; }
  • 125. 125/360 JSR-376: Modularization  Client (not a module)  Client (module) Direct call: Implementation.bar() Call on public implementation: bar: Implementation.bar() foo: Implementation.bar() Call on hidden implementation: Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation with package access Direct call: Implementation.bar() Call on public implementation: foo: Implementation.bar() bar: Unable to make private void net.ptidej.modularisation.kernel.impl.Implementation.bar() accessible: module ModularizationWithModulesLibrary1 does not "opens net.ptidej.modularisation.kernel.impl" to module ModularizationWithModulesClient1 Call on hidden implementation: Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client (in module ModularizationWithModulesClient1) cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation (in module ModularizationWithModulesLibrary1) with package access
  • 126. 126/360 JSR-376: Modularization  Client (not a module)  Client (module) Direct call: Implementation.bar() Call on public implementation: bar: Implementation.bar() foo: Implementation.bar() Call on hidden implementation: Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation with package access Direct call: Implementation.bar() Call on public implementation: foo: Implementation.bar() bar: Unable to make private void net.ptidej.modularisation.kernel.impl.Implementation.bar() accessible: module ModularizationWithModulesLibrary1 does not "opens net.ptidej.modularisation.kernel.impl" to module ModularizationWithModulesClient1 Call on hidden implementation: Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client (in module ModularizationWithModulesClient1) cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation (in module ModularizationWithModulesLibrary1) with package access Non-module can still access private methods
  • 127. 127/360 JSR-376: Modularization  Client (not a module)  Client (module) Direct call: Implementation.bar() Call on public implementation: bar: Implementation.bar() foo: Implementation.bar() Call on hidden implementation: Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation with package access Direct call: Implementation.bar() Call on public implementation: foo: Implementation.bar() bar: Unable to make private void net.ptidej.modularisation.kernel.impl.Implementation.bar() accessible: module ModularizationWithModulesLibrary1 does not "opens net.ptidej.modularisation.kernel.impl" to module ModularizationWithModulesClient1 Call on hidden implementation: Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client (in module ModularizationWithModulesClient1) cannot access a member of class net.ptidej.modularisation.kernel.impl.HiddenImplementation (in module ModularizationWithModulesLibrary1) with package access Non-module can still access private methods Modules cannot access private/package data
  • 128. 128/360 JSR-376: Modularization  Client  Provider module ModularizationWithModulesClient2 { requires ModularizationWithModulesLibrary2; uses net.ptidej.modularisation.kernel.Interface; } module ModularizationWithModulesLibrary2 { exports net.ptidej.modularisation.kernel; provides net.ptidej.modularisation.kernel.Interface with net.ptidej.modularisation.kernel.impl.Implementation; }
  • 129. 129/360 JSR-376: Modularization  Client implementation  Client output Implementation.bar() Call on public implementation: Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client (in module ModularizationWithModulesClient2) cannot access class net.ptidej.modularisation.kernel.impl.Implementation (in module ModularizationWithModulesLibrary2) because module ModularizationWithModulesLibrary2 does not export net.ptidej.modularisation.kernel.impl to module ModularizationWithModulesClient2 final ServiceLoader<Interface> providers = ServiceLoader.load(Interface.class); final Interface aki = providers.findFirst().orElse(null); aki.foo();
  • 130. 130/360 JSR-376: Modularization  Client implementation  Client output Implementation.bar() Call on public implementation: Exception in thread "main" java.lang.IllegalAccessException: class net.ptidej.modularisation.Client (in module ModularizationWithModulesClient2) cannot access class net.ptidej.modularisation.kernel.impl.Implementation (in module ModularizationWithModulesLibrary2) because module ModularizationWithModulesLibrary2 does not export net.ptidej.modularisation.kernel.impl to module ModularizationWithModulesClient2 No access to data not exported/provided, even if public! final ServiceLoader<Interface> providers = ServiceLoader.load(Interface.class); final Interface aki = providers.findFirst().orElse(null); aki.foo();
  • 134. 134/360 JSR-376: Modularization  Relation to OSGi – Open Service Gateway Initiative • From 05/2000, latest 12/2020 – Eclipse Foundation open-source project – Framework for developing and deploying • Modular programs and libraries • IoT and other constrained devices https://www.techtarget.com/searchnetworking/definition/OSGi
  • 135. 135/360 JSR-376: Modularization OSGi (Bundles)  Several class loaders – Cannot be used for the JDK – Allow “duplicate” packages – Allow multiple versions  Visibility JPMS (Modules)  One class loader – Can be used in the JDK – Disallow same packages – No versioning  Accessibility https://www.infoq.com/articles/java9-osgi-future-modularity/, https://www.infoq.com/articles/java9-osgi-future-modularity- part-2/, https://www.baeldung.com/java-illegal-reflective-access, https://en.wikipedia.org/wiki/OSGi
  • 136. 136/360 JSR-376: Modularization OSGi (Bundles)  “[B]uild dependencies and runtime dependencies can and often do differ” JPMS (Modules)  “[T]he module system should […] work [same] at compile time, run time…” Export-Package: org.example.foo; version=1.0.1, org.example.bar; version=2.1.0 Import-Package: org.example.foo; version='[1,2)', org.example.bar; version='[2.0,2.1)' module A { exports org.example.foo; exports org.example.bar; } module B { require A; } https://www.infoq.com/articles/java9-osgi-future-modularity/, https://www.infoq.com/articles/java9-osgi-future-modularity- part-2/, https://www.baeldung.com/java-illegal-reflective-access, https://en.wikipedia.org/wiki/OSGi
  • 137. 137/360 JEP-213: Milling Project Coin  From Java 7 – Allow @SafeVargs on private instance methods – Allow effectively-final variables as resources in the try- with-resources statement – Allow diamond with anonymous classes in some cases  From Java 8 – Remove underscore as legal identifier names  In Java 9 – Support for private methods in interfaces
  • 139. 139/360  Nothing to mention, so much work went into modularisation
  • 141. 141/360 Collection Factory Methods  No null values  No modification – Run-time exception public class Example1 { public static void main(final String[] args) { final List<String> list = List.of("Rick Deckard", "Roy Batty", "Harry Bryant", "Hannibal Chew", "Gaff", "Holden", "Leon Kowalski", "Taffey Lewis", "Pris", "Rachael", "J.F. Sebastian", "Dr. Eldon Tyrell", "Zhora", "Hodge", "Mary"); System.out.println(list); list.add("Paul Atreides"); } }
  • 142. 142/360 Collection Factory Methods  No null values  No modification – Run-time exception public class Example1 { public static void main(final String[] args) { final List<String> list = List.of("Rick Deckard", "Roy Batty", "Harry Bryant", "Hannibal Chew", "Gaff", "Holden", "Leon Kowalski", "Taffey Lewis", "Pris", "Rachael", "J.F. Sebastian", "Dr. Eldon Tyrell", "Zhora", "Hodge", "Mary"); System.out.println(list); list.add("Paul Atreides"); } } [Rick Deckard, Roy Batty, Harry Bryant, [...] Tyrell, Zhora, Hodge, Mary] Exception in thread "main" java.lang.UnsupportedOperationException at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142) at [...] at net.ptidej.newjava.collectionfactories.Example1.main(Example1.java:11)
  • 143. 143/360 JavaDB Removal  JavaDB was a repackaging of Apache Derby – Relational database – Open-source – Entirely in Java – Embedded JDBC driver
  • 144. 144/360 JEP-254: Compact Strings Problem and Solution  More space-efficient internal representation – Not about using UTF-8  From a UTF-16 char array to a byte array with an encoding flag – ISO-8859-1/Latin-1 (1 byte per char) or UTF-16 (2 bytes) – String-related classes and HotSpot intrinsic operations Consequences  Reduction in memory footprint  Substantial reductions of GC activity  Minor performance regressions in some corner cases
  • 145. 145/360 JEP-263: HiDPI Graphics  Java programs sized and rendered based on pixels  HiDPI displays can have 2 to 3 times higher pixel densities  Windows Direct2D APIs  Linux GTK+ 3 libraries https://stackoverflow.com/questions/52519777/java-swing-app-looks-tiny-on-high-dpi-screen-when-it-should-be-scaled-to-normal
  • 146. 146/360 JEP-266: More on Concurrency  “[A]synchronous stream processing with non-blocking back pressure” – https://www.reactive-streams.org/ https://www.baeldung.com/java-9-reactive-streams // Given final SubmissionPublisher<String> publisher = new SubmissionPublisher<>(); final EndSubscriber<String> subscriber = new EndSubscriber<>(); final List<String> items = List.of("1", "x", "2", "x", "3", "x"); // When publisher.subscribe(subscriber); items.forEach(publisher::submit); publisher.close(); // Then Awaitility.await().atMost(1000, TimeUnit.MILLISECONDS) .until(() -> subscriber.consumedElements.containsAll(items));
  • 147. 147/360 JEP-268: XML Catalogs  OASIS XML Catalogs standard, v1.1 – Map XML external identifiers into (local) URIs  Java API – javax.xml.catalog.* <?xml version="1.0"?> <!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public"> <public publicId="-//W3C//DTD XHTML 1.0 Strict//EN" uri="dtd/xhtml1/xhtml1-strict.dtd"/> <public publicId="-//W3C//DTD XHTML 1.0 Transitional//EN" uri="dtd/xhtml1/xhtml1-transitional.dtd"/> <public publicId="-//W3C//DTD XHTML 1.1//EN" uri="dtd/xhtml11/xhtml11-flat.dtd"/> </catalog>
  • 150. 150/360 JEP-282: jlink  Assemble, optimize some modules and their dependencies into a custom run-time image – JEP-220: Modular run-time images javac -d out module-info.java javac -d out --module-path out netptidejnewjavajlinkHelloWorld.java jlink --module-path "%JAVA_HOME%jmods";out --add-modules testJLinkModule --output CustomJRE cd CustomJRE/bib/ java --module testJLinkModule/net.ptidej.newjava.jlink.HelloWorld https://www.baeldung.com/jlink
  • 151. 151/360 JEP-295: jaotc  Ahead-of-time compilation – Compile Java classes to native code before launching the virtual machine https://stackoverflow.com/questions/45298045/how-do-i-run-a-class-compiled-with-jaotc javac Test.java jaotc Test.class jaotc --output libjava.base.so --module java.base java -XX:AOTLibrary=./Test.so Test
  • 154. 154/360 JEP-286: Local-variable Type Inference final List<String> list1 = new ArrayList<>(); System.out.println(list1); final var list2 = new ArrayList<String>(); System.out.println(list2); vs.
  • 156. 156/360 JEP-304: GC Interface  “Improve the source code isolation of different garbage collectors by introducing a clean garbage collector (GC) interface.” https://medium.com/@unmeshvjoshi/writing-your-own-garbage-collector-for-jdk12-8c83e3d0309b https://github.com/openjdk/jdk/blob/master/src/hotspot/share/gc/shared/collectedHeap.hpp#L90 class CollectedHeap : public CHeapObj<mtGC> { virtual jint initialize() = 0; virtual HeapWord* allocate_new_tlab(size_t min_size, size_t requested_size, size_t* actual_size) = 0; virtual HeapWord* mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded) = 0; // ...
  • 157. 157/360 JEP-307: Parallel Full GC  Improve G1 worst-case with full parallel GC – Before Java 9: Parallel GC – Since Java 9: G1 https://dev.java/evolution/
  • 158. 158/360 JEP-310: Application Class-Data Sharing  Improve startup and footprint https://www.geeksforgeeks.org/class-data-sharing-in-java/ java -XX:+UnlockCommercialFeatures-XX:+UseAppCDS -XX:DumpLoadedClassList=LoadedClasses.1st -jar AppCDS.jar java -XX:+UnlockCommercialFeatures -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=LoadedClasses.1st -XX:SharedArchiveFile=CustomSharedArchive.jsa -cp AppCDS.jar java -XX:UnlockCommercialFeatures -verbose -XShare:on -XX:+UseAppCDS -XX:SharedArchiveFile=CUstomSharedArchive.jsa -jar AppCDS.jar
  • 159. 159/360 JEP-312: Thread-local Handshakes  Callback on threads without performing a global VM safepoint  Possible and cheap to stop individual threads and not just all threads -XX:ThreadLocalHandshakes=<true|false>
  • 160. 160/360 JEP-316: Heap Allocation on Alternative Memory Devices  Availability of cheap NVDIMM memory – Non Volatile Dual In-line Memory Module https://blog.workinghardinit.work/2019/07/18/a-quick-intro-to-nvdimm-n/ -XX:AllocateHeapAt=<path>
  • 161. 161/360 JEP-317: Experimental Java-based JIT Compiler  Efficient JIT compiler for Java in Java  As of 18/09/30 https://www.graalvm.org/ https://www.javacodegeeks.com/2018/10/java-graalvm-database-stream-performance.html -XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
  • 163. 163/360 JEP-314: Additional Unicode Language-Tag Extensions  BCP 47 language tags – Codes to identify languages • en: English • en-US: English, in United States • km-Khmr-KH: Khmer, in Khmer script, in Cambodia • km-fonipa: Khmer, transcribed in IPA  Changes to many APIs – java.text.DateFormat, java.util.Currency, java.time.format.DateTimeFormatter, … https://help.keyman.com/developer/current-version/reference/bcp-47
  • 165. 165/360 JEP-296: Consolidated JDK Forest  Until Java 9 – Eight repos: root, corba, hotspot, jaxp, jaxws, jdk, langtools, and nashorn  Since Java 10 – One unified repository $ROOT/jdk/src/java.base ... $ROOT/langtools/src/java.compiler ...
  • 166. 166/360 JEP-296: Consolidated JDK Forest  Until Java 9 – Eight repos: root, corba, hotspot, jaxp, jaxws, jdk, langtools, and nashorn  Since Java 10 – One unified repository $ROOT/jdk/src/java.base ... $ROOT/langtools/src/java.compiler ... $ROOT/src/java.base $ROOT/src/java.compiler ...
  • 167. 167/360 JEP-313: Native-Header Generation Tool Removal  javah features (and more) now in javac javac HelloWorld.java javah HelloWorld javac -h jni -d bin HelloWorld.java vs.
  • 168. 168/360 JEP-319: Root Certificates  Default set of root Certification Authority (CA) certificates – Oracle Java SE Root CA becomes open source – OpenJDK can use the same certificates
  • 169. 169/360 JEP-322: Time-based Release Versioning  New version scheme final Version version = Runtime.version(); System.out.println(version); System.out.print("Feature: "); System.out.println(version.feature()); System.out.print("Interim: "); System.out.println(version.interim()); System.out.print("Update: "); System.out.println(version.update()); System.out.print("Patch: "); System.out.println(version.patch()); System.out.print("Build: "); System.out.println(version.build()); System.out.print("Optional: "); System.out.println(version.optional()); System.out.print("Pre: "); System.out.println(version.pre());
  • 170. 170/360 JEP-322: Time-based Release Versioning  New version scheme final Version version = Runtime.version(); System.out.println(version); System.out.print("Feature: "); System.out.println(version.feature()); System.out.print("Interim: "); System.out.println(version.interim()); System.out.print("Update: "); System.out.println(version.update()); System.out.print("Patch: "); System.out.println(version.patch()); System.out.print("Build: "); System.out.println(version.build()); System.out.print("Optional: "); System.out.println(version.optional()); System.out.print("Pre: "); System.out.println(version.pre()); 21.0.1+12-LTS-29 Feature: 21 Interim: 0 Update: 1 Patch: 0 Build: Optional[12] Optional: Optional[LTS-29] Pre: Optional.empty
  • 173. 173/360 JEP-181: Nest-based Access Control  Before Java 11 – Bridge method, e.g., access$000(Example1)  Since Java 11 – Direct access – Access to nest mates’ private members https://mkyong.com/java/java-11-nest-based-access-control/ public class Example1 { private String name = "I'm Example1!"; public class A { public void printName() { System.out.println(name); } } public class B { public void printName() { System.out.println(Example1.this.name); } public class B1 { public void printName() { System.out.println(Example1.this.name); } } } public static void main(final String[] args) { final Example1 e1 = new Example1(); final Example1.B b = e1.new B(); final Example1.B.B1 b1 = b.new B1(); b1.printName(); } }
  • 174. 174/360 JEP-181: Nest-based Access Control https://mkyong.com/java/java-11-nest-based-access-control/ public class Example2 { private String name = "I'm Example2!"; public class A { public void printName() { System.out.println(name); } } public class B { public void printName() { System.out.println(Example2.this.name); } public class B1 { public void printName() { System.out.println(Example2.this.name); } } } public static void main(final String[] args) { System.out.println(A.class.getNestHost()); System.out.println(A.class.isNestmateOf(B.class)); for (final Class<?> clazz : Example2.B.class.getNestMembers()) { System.out.println(clazz); } } }
  • 175. 175/360 JEP-181: Nest-based Access Control https://mkyong.com/java/java-11-nest-based-access-control/ public class Example2 { private String name = "I'm Example2!"; public class A { public void printName() { System.out.println(name); } } public class B { public void printName() { System.out.println(Example2.this.name); } public class B1 { public void printName() { System.out.println(Example2.this.name); } } } public static void main(final String[] args) { System.out.println(A.class.getNestHost()); System.out.println(A.class.isNestmateOf(B.class)); for (final Class<?> clazz : Example2.B.class.getNestMembers()) { System.out.println(clazz); } } } class net.ptidej.newjava.nest.Example2 true class net.ptidej.newjava.nest.Example2 class net.ptidej.newjava.nest.Example2$A class net.ptidej.newjava.nest.Example2$B class net.ptidej.newjava.nest.Example2$B$B1
  • 176. 176/360 JEP-323: Local-variable Syntax for Lambda Parameters interface Comparator<T> { int compare(final T a, final T b); } public class Example1 { public static void main(final String[] args) { final Comparator<String> comparator1 = new Comparator<>() { @Override public int compare(final String a, final String b) { return a.compareTo(b); } }; System.out.println(comparator1.compare("Hello", "World")); final Comparator<String> comparator2 = (a, b) -> a.compareTo(b); System.out.println(comparator2.compare("Hello", "World")); final Comparator<String> comparator3 = (String a, String b) -> a.compareTo(b); System.out.println(comparator3.compare("Hello", "World")); final Comparator<String> comparator4 = (final var a, final var b) -> a.compareTo(b); System.out.println(comparator4.compare("Hello", "World")); final Comparator<String> comparator5 = (@NonNull var a, @NonNull var b) -> a.compareTo(b); System.out.println(comparator5.compare("Hello", "World")); } }
  • 177. 177/360 JEP-323: Local-variable Syntax for Lambda Parameters interface Comparator<T> { int compare(final T a, final T b); } public class Example1 { public static void main(final String[] args) { final Comparator<String> comparator1 = new Comparator<>() { @Override public int compare(final String a, final String b) { return a.compareTo(b); } }; System.out.println(comparator1.compare("Hello", "World")); final Comparator<String> comparator2 = (a, b) -> a.compareTo(b); System.out.println(comparator2.compare("Hello", "World")); final Comparator<String> comparator3 = (String a, String b) -> a.compareTo(b); System.out.println(comparator3.compare("Hello", "World")); final Comparator<String> comparator4 = (final var a, final var b) -> a.compareTo(b); System.out.println(comparator4.compare("Hello", "World")); final Comparator<String> comparator5 = (@NonNull var a, @NonNull var b) -> a.compareTo(b); System.out.println(comparator5.compare("Hello", "World")); } } Now posssible
  • 179. 179/360 JEP-309: Dynamic .class Constants  Extend the class-file format with a new constant-pool form – CONSTANT_Dynamic  Avoid initialising “expansive” values – Also, no need to use volatile https://www.javacodegeeks.com/2018/08/hands-on-java-constantdynamic.html
  • 180. 180/360 JEP-309: Dynamic .class Constants Problem: How to share some “expensive” data among different threads? Solution: Singleton design pattern public class SomeExpensiveData { public SomeExpensiveData() { // Some very expensive (time, space) data to create System.out.println("tSomeExpensiveData instance created"); } }
  • 181. 181/360 JEP-309: Dynamic .class Constants public class MyCallable implements Callable<SomeExpensiveData> { private static MyCallable UniqueInstance; public static MyCallable getInstance() { if (MyCallable.UniqueInstance == null) { synchronized (MyCallable.class) { if (MyCallable.UniqueInstance == null) { MyCallable.UniqueInstance = new MyCallable(); } } } return MyCallable.UniqueInstance; } private volatile SomeExpensiveData someExpensiveData; private MyCallable() { this.someExpensiveData = new SomeExpensiveData(); } @Override public SomeExpensiveData call() throws Exception { return this.someExpensiveData; } }
  • 182. 182/360 JEP-309: Dynamic .class Constants public class MyCallable implements Callable<SomeExpensiveData> { private static MyCallable UniqueInstance; public static MyCallable getInstance() { if (MyCallable.UniqueInstance == null) { synchronized (MyCallable.class) { if (MyCallable.UniqueInstance == null) { MyCallable.UniqueInstance = new MyCallable(); } } } return MyCallable.UniqueInstance; } private volatile SomeExpensiveData someExpensiveData; private MyCallable() { this.someExpensiveData = new SomeExpensiveData(); } @Override public SomeExpensiveData call() throws Exception { return this.someExpensiveData; } } Not a true constant No caching, etc.
  • 183. 183/360 JEP-309: Dynamic .class Constants public class MyCallable implements Callable<SomeExpensiveData> { private static MyCallable UniqueInstance; public static MyCallable getInstance() { if (MyCallable.UniqueInstance == null) { synchronized (MyCallable.class) { if (MyCallable.UniqueInstance == null) { MyCallable.UniqueInstance = new MyCallable(); } } } return MyCallable.UniqueInstance; } private volatile SomeExpensiveData someExpensiveData; private MyCallable() { this.someExpensiveData = new SomeExpensiveData(); } @Override public SomeExpensiveData call() throws Exception { return this.someExpensiveData; } } Not a true constant No caching, etc. Eager initialisation
  • 184. 184/360 JEP-309: Dynamic .class Constants  Dynamic constants – Created once at run-time – Can be shared among threads – Can be cached, optimised, etc. Problem: How to create dynamically a constant Solution: CONSTANT_Dynamic
  • 185. 185/360 JEP-309: Dynamic .class Constants  Dynamic constants, javac vs. java – Cannot be created from source code • As of 24/03/24 – Can be created in the byte code  Byte code generation, manipulation library – Create, modify Java classes at run-time
  • 186. 186/360 JEP-309: Dynamic .class Constants final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class) .method(ElementMatchers.named("call")).intercept(FixedValue.value( JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make(); final Constructor<? extends Callable> loaded = unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor(); final Callable<SomeExpensiveData> first = loaded.newInstance(); final Callable<SomeExpensiveData> second = loaded.newInstance(); System.out.println("tCallable instances created"); assertThat(first.call()).isEqualTo(second.call());
  • 187. 187/360 JEP-309: Dynamic .class Constants final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class) .method(ElementMatchers.named("call")).intercept(FixedValue.value( JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make(); final Constructor<? extends Callable> loaded = unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor(); final Callable<SomeExpensiveData> first = loaded.newInstance(); final Callable<SomeExpensiveData> second = loaded.newInstance(); System.out.println("tCallable instances created"); assertThat(first.call()).isEqualTo(second.call()); test_CONSTANT_Dynamic() Callable instances created SomeExpensiveData instance created
  • 188. 188/360 JEP-309: Dynamic .class Constants final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class) .method(ElementMatchers.named("call")).intercept(FixedValue.value( JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make(); final Constructor<? extends Callable> loaded = unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor(); final Callable<SomeExpensiveData> first = loaded.newInstance(); final Callable<SomeExpensiveData> second = loaded.newInstance(); System.out.println("tCallable instances created"); assertThat(first.call()).isEqualTo(second.call()); test_CONSTANT_Dynamic() Callable instances created SomeExpensiveData instance created Lazy initialisation: two instances created, but not SomExpensiveData
  • 189. 189/360 JEP-309: Dynamic .class Constants final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class) .method(ElementMatchers.named("call")).intercept(FixedValue.value( JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make(); final Constructor<? extends Callable> loaded = unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor(); final Callable<SomeExpensiveData> first = loaded.newInstance(); final Callable<SomeExpensiveData> second = loaded.newInstance(); System.out.println("tCallable instances created"); assertThat(first.call()).isEqualTo(second.call()); test_CONSTANT_Dynamic() Callable instances created SomeExpensiveData instance created Lazy initialisation: two instances created, but not SomExpensiveData SomExpensiveData created only once, with first call()
  • 190. 190/360 JEP-309: Dynamic .class Constants final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class) .method(ElementMatchers.named("call")).intercept(FixedValue.value( JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make(); final Constructor<? extends Callable> loaded = unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor(); final Callable<SomeExpensiveData> first = loaded.newInstance(); final Callable<SomeExpensiveData> second = loaded.newInstance(); System.out.println("tCallable instances created"); assertThat(first.call()).isEqualTo(second.call()); // (version 17 : 61.0, super bit) public class net.bytebuddy.[...].Callable$ByteBuddy$7xbn1EIQ implements java.util.concurrent.Callable public java.lang.Object call() throws java.lang.Exception; 0 ldc <Dynamic> 0 _ net.ptidej.newjava.constantdynamic.SomeExpensiveData [28] 2 areturn public Callable$ByteBuddy$7xbn1EIQ(); 0 aload_0 [this] 1 invokespecial java.lang.Object() [29] 4 return Bootstrap methods: 0 : # 24 invokestatic java/lang/invoke/ConstantBootstraps.invoke:([...])Ljava/lang/Object; Method arguments: #17 net/ptidej/newjava/constantdynamic/SomeExpensiveData.<init>:()V
  • 191. 191/360 JEP-309: Dynamic .class Constants final Unloaded<Callable> unloaded = new ByteBuddy().subclass(Callable.class) .method(ElementMatchers.named("call")).intercept(FixedValue.value( JavaConstant.Dynamic.ofInvocation(SomeExpensiveData.class.getConstructor()))).make(); final Constructor<? extends Callable> loaded = unloaded.load(Example2.class.getClassLoader()).getLoaded().getConstructor(); final Callable<SomeExpensiveData> first = loaded.newInstance(); final Callable<SomeExpensiveData> second = loaded.newInstance(); System.out.println("tCallable instances created"); assertThat(first.call()).isEqualTo(second.call()); // (version 17 : 61.0, super bit) public class net.bytebuddy.[...].Callable$ByteBuddy$7xbn1EIQ implements java.util.concurrent.Callable public java.lang.Object call() throws java.lang.Exception; 0 ldc <Dynamic> 0 _ net.ptidej.newjava.constantdynamic.SomeExpensiveData [28] 2 areturn public Callable$ByteBuddy$7xbn1EIQ(); 0 aload_0 [this] 1 invokespecial java.lang.Object() [29] 4 return Bootstrap methods: 0 : # 24 invokestatic java/lang/invoke/ConstantBootstraps.invoke:([...])Ljava/lang/Object; Method arguments: #17 net/ptidej/newjava/constantdynamic/SomeExpensiveData.<init>:()V CONSTANT_Dynamic with bootstrap method
  • 192. 192/360 JEP-331: Low-overhead Heap Profiling  Since Java 6 – No more JVM Profiler Interface (JVMPI) – No more JVM Debug Interface (JVMDI) – Replaced by JVM Tool Interface (JVMTI)  Sampling of Java heap allocations – All allocations – Low-overhead – Well-defined API – Live, dead objects https://docs.oracle.com/en/java/javase/11/docs/specs/jvmti.html
  • 194. 194/360 JEP-333: Scalable Low-latency GC  Z Garbage Collector – GC pause no more than 10ms – Handle megabyte to terabyte heaps – No more than 15% throughput reduction wrt. G1 – Foundation for future features and optimisations – (Only on 64bit operating systems) -XX:+UnlockExperimentalVMOptions -XX:+UseZGC
  • 196. 196/360 JEP-320: Java EE and CORBA Modules Removal  Since Java 1.2 – OMG CORBA API – ORB implementation – CosNaming implementation – idlj compiler – Support for IDL and IIOP in rmic compiler – No significant interest in CORBA anymore  Since Java 6 – Full Web Services stack – Now available from third parties  Deprecated in Java 9
  • 197. 197/360 JEP-321: HTTP Client  Problems with HttpURLConnection API – Designed for (now dead) protocols (gopher…) – Designed before HTTP/1.1 – Too abstract – Hard to use – Badly documented – Blocking mode only – Very hard maintenance
  • 198. 198/360 JEP-321: HTTP Client  Three core classes – HttpClient as a container for configuration information common to multiple requests – HttpRequest for requests sent by HttpClient – HttpResponse for the result of an HttpRequest https://www.baeldung.com/java-9-http-client
  • 199. 199/360 JEP-321: https://www.baeldung.com/java-9-http-client final HttpRequest request = HttpRequest.newBuilder() .uri(new URI("https://postman-echo.com/get")) .version(HttpClient.Version.HTTP_2) .timeout(Duration.ofSeconds(10)) .header("key1", "value1") .header("key2", "value2") .GET() .build(); final HttpClient client = HttpClient.newHttpClient(); final HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body());
  • 200. 200/360 JEP-321: https://www.baeldung.com/java-9-http-client final HttpRequest request = HttpRequest.newBuilder() .uri(new URI("https://postman-echo.com/get")) .version(HttpClient.Version.HTTP_2) .timeout(Duration.ofSeconds(10)) .header("key1", "value1") .header("key2", "value2") .GET() .build(); final HttpClient client = HttpClient.newHttpClient(); final HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); { "args": {}, "headers": { "x-forwarded-proto": "https", "x-forwarded-port": "443", "host": "postman-echo.com", "x-amzn-trace-id": "Root=1-660163f4-038cfd7075f93fad1e79f19e", "key1": "value1", "key2": "value2", "user-agent": "Java-http-client/21.0.1" }, "url": "https://postman-echo.com/get" }
  • 201. 201/360 JEP-327: Unicode 10  Major version of the Unicode Standard  Support – Character and String in java.lang – NumericShaper in java.awt.font – Bidi, BreakIterator, Normalizer in java.text
  • 202. 202/360 JEP-335: Nashorn Deprecation  Since Java 8 – JEP-174  ECMAScript changes rapidly – Language – APIs  Maintenance challenges – Deprecate Nashorn, its APIs, and jjs
  • 204. 204/360 JEP-328: Flight Recorder  Monitoring tool – Collects information about the events in a JVM – An event • Name • Timestamp • Other data – Thread data, state of the heap, etc. https://www.baeldung.com/java-flight-recorder-monitoring -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=duration=200s,filename=flight.jfr
  • 206. 206/360 JEP-330: Single-file Source-code Programs Launching  Lower the (early) learning curve – But no dependency management java –cp some.jar HelloWorld.java
  • 207. 207/360 JEP-336: Pack200 Tools and API Deprecation  Since Java 5 – Compression scheme for JAR files – To accommodate 56k modems  Since Java 9 (and JEP-220) – Modules – Compression – No more applets – Maintenance challenges – Modularisation challenges
  • 212. 212/360 JEP-344: Abortable Mixed Collections  Ability for G1 to abort its collection pauses  G1 predicts the number of regions to collect and proceeds only with abortable ones  Lower pause latency and higher probability to achieve pause-time target https://blogs.oracle.com/javamagazine/post/understanding-the-jdks-new-superfast-garbage-collectors -XX:G1MixedGCCountTarget=<number of mixed garbage collections>
  • 213. 213/360 JEP-346: Unused Committed Memory Prompt Return  G1 automatically returns heap memory to the operating system when idle -XX:G1PeriodicGCInterval=<true|false> -XX:G1PeriodicGCInvokesConcurrent=<true|false> -XX:G1PeriodicGCSystemLoadThreshold=<average 1-minute system load>
  • 215. 215/360 JEP-334: JVM Constants API  API to describes some class-file and run- time elements (e.g., constants) https://iampravo.medium.com/java-12-features-and-highlights-81938474cd31 public class Example1 { public static void main(final String[] args) { final ClassDesc example1ClassDesc = ClassDesc.of("[...].constantsapi", "Example1"); final MethodTypeDesc mainMethodTypeDesc = MethodTypeDesc.of(example1ClassDesc); final MethodHandleDesc mainMethodHandleDesc = MethodHandleDesc.ofMethod( DirectMethodHandleDesc.Kind.STATIC, example1ClassDesc, "main", mainMethodTypeDesc); System.out.println("Class descriptor: " + example1ClassDesc); System.out.println("Method type descriptor: " + mainMethodTypeDesc); System.out.println("Method handle descriptor: " + mainMethodHandleDesc); } }
  • 216. 216/360 JEP-334: JVM Constants API  API to describes some class-file and run- time elements (e.g., constants) https://iampravo.medium.com/java-12-features-and-highlights-81938474cd31 public class Example1 { public static void main(final String[] args) { final ClassDesc example1ClassDesc = ClassDesc.of("[...].constantsapi", "Example1"); final MethodTypeDesc mainMethodTypeDesc = MethodTypeDesc.of(example1ClassDesc); final MethodHandleDesc mainMethodHandleDesc = MethodHandleDesc.ofMethod( DirectMethodHandleDesc.Kind.STATIC, example1ClassDesc, "main", mainMethodTypeDesc); System.out.println("Class descriptor: " + example1ClassDesc); System.out.println("Method type descriptor: " + mainMethodTypeDesc); System.out.println("Method handle descriptor: " + mainMethodHandleDesc); } } Class descriptor: ClassDesc[Example1] Method type descriptor: MethodTypeDesc[()Example1] Method handle descriptor: MethodHandleDesc[STATIC/Example1::main()Example1]
  • 218. 218/360 JEP-230: Microbenchmark Suite  Java Microbenchmark Harness (JMH) – An annotation-based DSL • @State, @Fork, @Warmup, @Measurement, @Benchmark…  Microbenchmarks suite integrated into OpenJDK source code https://cl4es.github.io/2018/11/16/JEP-230-Microbenchmarks-Suite.html make build-microbenchmark
  • 219. 219/360 JEP-230: Microbenchmark Suite  Java Microbenchmark Harness (JMH) – An annotation-based DSL • @State, @Fork, @Warmup, @Measurement, @Benchmark…  Microbenchmarks suite integrated into OpenJDK source code https://cl4es.github.io/2018/11/16/JEP-230-Microbenchmarks-Suite.html make build-microbenchmark build/$PROFILE/images/test/micro/benchmarks.jar
  • 220. 220/360 JEP-230: Microbenchmark Suite  Run one java.util.UUIDBench benchmark – https://github.com/openjdk/jdk/blob/master/test/mi cro/org/openjdk/bench/java/util/UUIDBench.java https://cl4es.github.io/2021/01/04/Investigating-MD5-Overheads.html make test TEST=micro:UUIDBench.fromType3Bytes
  • 221. 221/360 JEP-230: Microbenchmark Suite  Run one java.util.UUIDBench benchmark – https://github.com/openjdk/jdk/blob/master/test/mi cro/org/openjdk/bench/java/util/UUIDBench.java https://cl4es.github.io/2021/01/04/Investigating-MD5-Overheads.html make test TEST=micro:UUIDBench.fromType3Bytes Benchmark Score Error Units fromType3Bytes 1.460 ± 0.089 ops/us
  • 222. 222/360 JEP-230: Microbenchmark Suite  Benchmarking the JVM is difficult – Just-in-time compiler – Dead code elimination – Loop unrolling – Method inlining – … – Warmup iterations – Iteration durations – … https://www.oracle.com/technical-resources/articles/java/architect-benchmarking.html
  • 227. 227/360 JEP-351: Unused Memory Uncommit  ZGC automatically returns heap memory to the operating system when idle – Cf. JEP-346 -XX:ZUncommitDelay=<seconds>
  • 229. 229/360 JEP-353: Legacy Socket API Reimplementation  Reimplementations – java.net.Socket – java.net.ServerSocket  Simpler, modern  Easier to maintain, debug  Ready for user-mode threads – Fibers, Project Loom
  • 234. 234/360 -XX:+ShowCodeDetailsInExceptionMessages JEP-358: Helpful NullPointerExceptions  Describe precisely which variable was null class Employee { String getName() { // return "Bob"; return null; } } public class Example1 { public static void main(final String[] args) { final Employee e = new Employee(); e.getName().toString(); } }
  • 235. 235/360 -XX:+ShowCodeDetailsInExceptionMessages JEP-358: Helpful NullPointerExceptions  Describe precisely which variable was null class Employee { String getName() { // return "Bob"; return null; } } public class Example1 { public static void main(final String[] args) { final Employee e = new Employee(); e.getName().toString(); } } Exception in thread "main" java.lang.NullPointerException at net.ptidej.newjava.helpfulnullpointerexceptions.Example1.main(Example1.java:13)
  • 236. 236/360 -XX:+ShowCodeDetailsInExceptionMessages JEP-358: Helpful NullPointerExceptions  Describe precisely which variable was null class Employee { String getName() { // return "Bob"; return null; } } public class Example1 { public static void main(final String[] args) { final Employee e = new Employee(); e.getName().toString(); } } Exception in thread "main" java.lang.NullPointerException at net.ptidej.newjava.helpfulnullpointerexceptions.Example1.main(Example1.java:13) Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toString()" because the return value of "[...].Employee.getName()" is null at net.ptidej.newjava.helpfulnullpointerexceptions.Example1.main(Example1.java:13)
  • 237. 237/360 JEP-361: switch Expressions https://medium.com/@imagarg/switch-expression-jep-361-3b5649ec36c9 private static int getDayLength(final Day day) { int numberOfCharacters = 0; switch (day) { case MONDAY: case FRIDAY: case SUNDAY: numberOfCharacters = 6; break; case TUESDAY: numberOfCharacters = 7; break; case THURSDAY: case SATURDAY: numberOfCharacters = 8; break; case WEDNESDAY: numberOfCharacters = 9; break; default: throw new IllegalArgumentException(); } return numberOfCharacters; } private static int getDayLength(final Day day) { int result = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; default -> throw new IllegalArgumentException(); }; return result; } enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; }
  • 239. 239/360 JEP-345: NUMA-Aware Memory Allocation  NUMA-aware memory allocation to increase G1 performance – Non-uniform memory access – Multi-socket computers • E.g., HP Z820 -XX:UseParallelGC=<true|false>
  • 240. 240/360 JEP-345: NUMA-Aware Memory Allocation  NUMA-aware memory allocation to increase G1 performance – Non-uniform memory access – Multi-socket computers • E.g., HP Z820 -XX:UseParallelGC=<true|false> Two CPUs, with their own DIMMs