Download IObit Driver Booster Pro Crack Latest Version [Updated]

349 views 189 slides Apr 03, 2025
Slide 1
Slide 1 of 466
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53
Slide 54
54
Slide 55
55
Slide 56
56
Slide 57
57
Slide 58
58
Slide 59
59
Slide 60
60
Slide 61
61
Slide 62
62
Slide 63
63
Slide 64
64
Slide 65
65
Slide 66
66
Slide 67
67
Slide 68
68
Slide 69
69
Slide 70
70
Slide 71
71
Slide 72
72
Slide 73
73
Slide 74
74
Slide 75
75
Slide 76
76
Slide 77
77
Slide 78
78
Slide 79
79
Slide 80
80
Slide 81
81
Slide 82
82
Slide 83
83
Slide 84
84
Slide 85
85
Slide 86
86
Slide 87
87
Slide 88
88
Slide 89
89
Slide 90
90
Slide 91
91
Slide 92
92
Slide 93
93
Slide 94
94
Slide 95
95
Slide 96
96
Slide 97
97
Slide 98
98
Slide 99
99
Slide 100
100
Slide 101
101
Slide 102
102
Slide 103
103
Slide 104
104
Slide 105
105
Slide 106
106
Slide 107
107
Slide 108
108
Slide 109
109
Slide 110
110
Slide 111
111
Slide 112
112
Slide 113
113
Slide 114
114
Slide 115
115
Slide 116
116
Slide 117
117
Slide 118
118
Slide 119
119
Slide 120
120
Slide 121
121
Slide 122
122
Slide 123
123
Slide 124
124
Slide 125
125
Slide 126
126
Slide 127
127
Slide 128
128
Slide 129
129
Slide 130
130
Slide 131
131
Slide 132
132
Slide 133
133
Slide 134
134
Slide 135
135
Slide 136
136
Slide 137
137
Slide 138
138
Slide 139
139
Slide 140
140
Slide 141
141
Slide 142
142
Slide 143
143
Slide 144
144
Slide 145
145
Slide 146
146
Slide 147
147
Slide 148
148
Slide 149
149
Slide 150
150
Slide 151
151
Slide 152
152
Slide 153
153
Slide 154
154
Slide 155
155
Slide 156
156
Slide 157
157
Slide 158
158
Slide 159
159
Slide 160
160
Slide 161
161
Slide 162
162
Slide 163
163
Slide 164
164
Slide 165
165
Slide 166
166
Slide 167
167
Slide 168
168
Slide 169
169
Slide 170
170
Slide 171
171
Slide 172
172
Slide 173
173
Slide 174
174
Slide 175
175
Slide 176
176
Slide 177
177
Slide 178
178
Slide 179
179
Slide 180
180
Slide 181
181
Slide 182
182
Slide 183
183
Slide 184
184
Slide 185
185
Slide 186
186
Slide 187
187
Slide 188
188
Slide 189
189
Slide 190
190
Slide 191
191
Slide 192
192
Slide 193
193
Slide 194
194
Slide 195
195
Slide 196
196
Slide 197
197
Slide 198
198
Slide 199
199
Slide 200
200
Slide 201
201
Slide 202
202
Slide 203
203
Slide 204
204
Slide 205
205
Slide 206
206
Slide 207
207
Slide 208
208
Slide 209
209
Slide 210
210
Slide 211
211
Slide 212
212
Slide 213
213
Slide 214
214
Slide 215
215
Slide 216
216
Slide 217
217
Slide 218
218
Slide 219
219
Slide 220
220
Slide 221
221
Slide 222
222
Slide 223
223
Slide 224
224
Slide 225
225
Slide 226
226
Slide 227
227
Slide 228
228
Slide 229
229
Slide 230
230
Slide 231
231
Slide 232
232
Slide 233
233
Slide 234
234
Slide 235
235
Slide 236
236
Slide 237
237
Slide 238
238
Slide 239
239
Slide 240
240
Slide 241
241
Slide 242
242
Slide 243
243
Slide 244
244
Slide 245
245
Slide 246
246
Slide 247
247
Slide 248
248
Slide 249
249
Slide 250
250
Slide 251
251
Slide 252
252
Slide 253
253
Slide 254
254
Slide 255
255
Slide 256
256
Slide 257
257
Slide 258
258
Slide 259
259
Slide 260
260
Slide 261
261
Slide 262
262
Slide 263
263
Slide 264
264
Slide 265
265
Slide 266
266
Slide 267
267
Slide 268
268
Slide 269
269
Slide 270
270
Slide 271
271
Slide 272
272
Slide 273
273
Slide 274
274
Slide 275
275
Slide 276
276
Slide 277
277
Slide 278
278
Slide 279
279
Slide 280
280
Slide 281
281
Slide 282
282
Slide 283
283
Slide 284
284
Slide 285
285
Slide 286
286
Slide 287
287
Slide 288
288
Slide 289
289
Slide 290
290
Slide 291
291
Slide 292
292
Slide 293
293
Slide 294
294
Slide 295
295
Slide 296
296
Slide 297
297
Slide 298
298
Slide 299
299
Slide 300
300
Slide 301
301
Slide 302
302
Slide 303
303
Slide 304
304
Slide 305
305
Slide 306
306
Slide 307
307
Slide 308
308
Slide 309
309
Slide 310
310
Slide 311
311
Slide 312
312
Slide 313
313
Slide 314
314
Slide 315
315
Slide 316
316
Slide 317
317
Slide 318
318
Slide 319
319
Slide 320
320
Slide 321
321
Slide 322
322
Slide 323
323
Slide 324
324
Slide 325
325
Slide 326
326
Slide 327
327
Slide 328
328
Slide 329
329
Slide 330
330
Slide 331
331
Slide 332
332
Slide 333
333
Slide 334
334
Slide 335
335
Slide 336
336
Slide 337
337
Slide 338
338
Slide 339
339
Slide 340
340
Slide 341
341
Slide 342
342
Slide 343
343
Slide 344
344
Slide 345
345
Slide 346
346
Slide 347
347
Slide 348
348
Slide 349
349
Slide 350
350
Slide 351
351
Slide 352
352
Slide 353
353
Slide 354
354
Slide 355
355
Slide 356
356
Slide 357
357
Slide 358
358
Slide 359
359
Slide 360
360
Slide 361
361
Slide 362
362
Slide 363
363
Slide 364
364
Slide 365
365
Slide 366
366
Slide 367
367
Slide 368
368
Slide 369
369
Slide 370
370
Slide 371
371
Slide 372
372
Slide 373
373
Slide 374
374
Slide 375
375
Slide 376
376
Slide 377
377
Slide 378
378
Slide 379
379
Slide 380
380
Slide 381
381
Slide 382
382
Slide 383
383
Slide 384
384
Slide 385
385
Slide 386
386
Slide 387
387
Slide 388
388
Slide 389
389
Slide 390
390
Slide 391
391
Slide 392
392
Slide 393
393
Slide 394
394
Slide 395
395
Slide 396
396
Slide 397
397
Slide 398
398
Slide 399
399
Slide 400
400
Slide 401
401
Slide 402
402
Slide 403
403
Slide 404
404
Slide 405
405
Slide 406
406
Slide 407
407
Slide 408
408
Slide 409
409
Slide 410
410
Slide 411
411
Slide 412
412
Slide 413
413
Slide 414
414
Slide 415
415
Slide 416
416
Slide 417
417
Slide 418
418
Slide 419
419
Slide 420
420
Slide 421
421
Slide 422
422
Slide 423
423
Slide 424
424
Slide 425
425
Slide 426
426
Slide 427
427
Slide 428
428
Slide 429
429
Slide 430
430
Slide 431
431
Slide 432
432
Slide 433
433
Slide 434
434
Slide 435
435
Slide 436
436
Slide 437
437
Slide 438
438
Slide 439
439
Slide 440
440
Slide 441
441
Slide 442
442
Slide 443
443
Slide 444
444
Slide 445
445
Slide 446
446
Slide 447
447
Slide 448
448
Slide 449
449
Slide 450
450
Slide 451
451
Slide 452
452
Slide 453
453
Slide 454
454
Slide 455
455
Slide 456
456
Slide 457
457
Slide 458
458
Slide 459
459
Slide 460
460
Slide 461
461
Slide 462
462
Slide 463
463
Slide 464
464
Slide 465
465
Slide 466
466

About This Presentation

Direct License file Link Below👇

https://up-community.wiki/ds/

With Driver Booster 12 Pro Crack software, you can one-click to keep 15000000+ PC drivers updated for top PC performance.


Slide Content

Yann-Gaël Guéhéneuc
(/jan/, he/il)
Work licensed under Creative Commons
BY-NC-SA 4.0 International
New Java
[email protected]
Version 0.24
2025/03/18

2/466
Any questions/comments are welcome at
[email protected]
Source code available at
https://github.com/ptidejteam/tutorials-NewJava

3/466
Patrick Naughton
Scott McNealy
Mike Sheridan James Gosling
1991

4/466

5/466
Naming 
Java
–1995/05/23
–Language

JDK (Java Development Kit)
–Compiler (Java Language Specification)
–VM (Java Virtual Machine Specification)
–APIs/Libraries (Java Class Libraries)

6/466
Process 
JCP: Java Community Process
–Established in 1998
–JSR-387 describes JCP v2.11

7/466
Documents 
JLSs: Java Language Specifications
– What isJava 
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-di fference-or-relation-between-jls-jsr-and-jep

8/466
About the JDK
https://medium.com/@zaam.oussama/java-development-kit-jdk-exploring-its-components-and-functionality-8f6d6c2a0 46c

9/466
About the JDK 
Compiler
– javac: compiler

Development
– javadoc: documentation
– jar: packaging
– jdb: debugger

Management
– jconsole: GUI
– javaw: VM

Libraries
– java.lang.…: mandatory
classes
– java.awt.…: graphical
framework
– javax.…: extensions
https://medium.com/@zaam.oussama/java-development-kit-jdk-exploring-its-components-and-functionality-8f6d6c2a0 46c

10/466
About the JDK
https://medium.com/@zaam.oussama/java-development-kit-jdk-exploring-its-components-and-functionality-8f6d6c2a0 46c

11/466
About the JDK
https://medium.com/@zaam.oussama/java-development-kit-jdk-exploring-its-components-and-functionality-8f6d6c2a0 46c

12/466
About the JDK 
Loading: JVM loads bytecode in .class files

Verification: JVM verifies the bytecode for
Java’s safety and security rules

Execution: JVM interprets or compiles
bytecode into native machine instructions

Optimization: JIT compiler optimises
bytecode for faster execution
https://medium.com/@zaam.oussama/java-development-kit-jdk-exploring-its-components-and-functionality-8f6d6c2a0 46c

13/466
About the JDK 
Modularisation
– Since Java 9 (2017) 
Development
– jlink: assembles and
optimises a set of modules
and their dependencies into
a custom runtime image
– jpackage: generates
installable packages for
(non-)modular programs
– jmod: packages modules
with native libraries or other
configuration files (for jlink)

Runtime
– A JDK image is a runtime
image with development
tools
– A runtime image is a set of
folders/files
– URI scheme jrt:/for
naming stored modules,
classes, and resources
– No regression
• Startup
• Static footprint
• Dynamic footprint

14/466
About the JDK
https://bugs.openjdk.org/secure/attachment/72525/jdk.png

15/466
Disclaimer

16/466
Too
Many
Features
Disclaimer
No
Preview
No
Incubator
Or just a few…

17/466
Organisation 
Per release
–With some cross-references

Three categories
–Language
–JVM
–APIs
Misc
+

18/466
In Summary (With Few Examples) 
Language
– Reduce risk of bugs
• trywith resources
– Simplify coding
• switchwith Strings, expressions, pattern matching
– Improve typing
• Diamond operator, annotations, inferences
– Make the language more functional
•λ-expressions (+ rewrite of many APIs)
– Control finely accessibility/visibility
• Modules, records, sealed classes, hidden classes

19/466
In Summary (With Few Examples) 
JVM
– APIs
• Tools
• GCs
– Release
• Statically-linked libraries
– Performance
• JIT
– Graal VM
• GCs
– Implementations
– NUMA

20/466
In Summary (With Few Examples) 
APIs
–Reduce risk of bugs
• Concurrency
• Date and Time
–Simplify coding
• New file I/O
• HTTP client and server
• Foreign Function and Memory API

21/466
In Summary (With Few Examples) 
Misc.
–Coding
• jshell
• Java files launching
• Instance main method
–Release
• jlinkand jpackage
–Performance
• jaotc

22/466
Java 5
Java 6
2004/09/30
2006/12/11

23/466
LANGUAGE (ONLY)

24/466
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();
}
}

25/466
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
);
}

26/466
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()

27/466
Enums EnumSimulated 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();
}
}

28/466
Enums EnumSimulated 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

29/466
Enums EnumSimulated 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

30/466
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
// ...
}

31/466
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

32/466
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
;

33/466
Java 7
2011/07/07 2011/07/07

34/466
LANGUAGE

35/466
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
;
}

36/466
tryWith 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();
}

37/466
Diamond Operator <>
https://www.baeldung.com/java-diamond-operator
List<String>
cars
=
new
ArrayList<String>();
List<String>
cars
=
new
ArrayList<>();
vs.

38/466
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.

39/466
Binary Integer Literals
https://www.geeksforgeeks.org/java-program-to-illustrate-u se-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;

40/466
Underscores in Numeric Literals
int
i
= 12_34_56;
System.
out
.println(
i
);
https://www.geeksforgeeks.org/using-underscore-numeric-lite rals-java/

41/466
Multiple Exception Types 
Multiple exception types

Multiple exceptions rethrown
with improved type checking

42/466
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
);
}
}
// ...

43/466
JVM

44/466
JSR-292: invokedynamic 
invokestatic, for class methods

invokevirtual, for instance methods

invokeinterface, for interface methods

invokespecial, for instance initialisation,
superclass, and private methods

45/466
JSR-292: invokedynamic
Gilad Bracha, 2005

46/466
JSR-292: invokedynamic 
invokedynamicindicates 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'
);

47/466
APIS

48/466
JSR-166: Concurrency Utilities 
Concurrency utilities under JSR 166

java.util.concurrentwants 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-slid es.pdf

49/466
JSR-166: Concurrency Utilities
https://www.uml-diagrams.org/java-7-concurrent-uml-class-d iagram-example.html

50/466
JSR-166: Concurrency Utilities
https://www.uml-diagrams.org/java-7-concurrent-uml-class-d iagram-example.html

51/466
JSR-166: Concurrency Utilities
https://www.uml-diagrams.org/java-7-concurrent-uml-class-d iagram-example.html

52/466
JSR-166: Concurrency Utilities
https://gee.cs.oswego.edu/dl/concurrency-interest/jsr166-slid es.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.

53/466
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-slid es.pdf

54/466
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

55/466
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/

56/466
JSR-166: Concurrency Utilities
https://www.geeksforgeeks.org/atomic-variables-in-java-wit h-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();
}
}

57/466
JSR-203: New File I/O Library 
Extensive File I/O API

Socket channel API

Asynchronous I/O API

58/466
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:\\Documents\\Tutorials\\220926 - New Java"
);
final
String
fileName
=
"Example1FileVisitor.java"
;
final
FileVisitorImpl
visitor
=
new
FileVisitorImpl(
fileName
,
startPath
);
Files.walkFileTree(
startPath
,
visitor
);
}
}

59/466
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
;
}
}

60/466
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:\\Documents\\Tutorials\\220926 - New Java\\ReceivedFile.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_chan nel.htm

61/466
JSR-203: New File I/O Library 
Socket channel API –Server
https://www.tutorialspoint.com/java_nio/java_nio_socket_chan nel.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:\\\\Documents\\\\Tutorials\\\\220926 - New Java\\\\Patterns.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();
}

62/466
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_chan nel.htm

63/466
JSR-203: New File I/O Library 
Asynchronous I/O API
“The asynchronous channel APIs were
introduced into the existing
java.nio.channelspackage […] by
prefixing […] with Asynchronous”

64/466
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)

65/466
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.h tml
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();
// ...

66/466
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

67/466
Java 8
2014/03/18

68/466
LANGUAGE

69/466
default, staticInterface 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());
}

70/466
default, staticInterface 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

71/466
default, staticInterface 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());
}

72/466
default, staticInterface 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());
}

73/466
default, staticInterface 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());

74/466
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

75/466
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!"
));
}

76/466
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!"
));
}

77/466
JSR-335, JEP-126: λExpressions 
Solution
–Simple syntactic sugar
–Set of functionalinterfaces
–Libraries using these interfaces

78/466
JSR-335, JEP-126: λExpressions 
Solution
–Simple syntactic sugar –Set of functionalinterfaces
–Libraries using these interfaces

79/466
JSR-335, JEP-126: λExpressions 
Solution
–Simple syntactic sugar –Set of functionalinterfaces
–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!"
));
}

80/466
JSR-335, JEP-126: λExpressions 
Solution
–Simple syntactic sugar –Set of functionalinterfaces
–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!"
));
}

81/466
JSR-335, JEP-126: λExpressions 
Solution
–Simple syntactic sugar
–Set of functionalinterfaces –Libraries using these interfaces
http://blog.orfjackal.net/2014/07/java-8-functional-int erface-naming-guide.html

82/466
JSR-335, JEP-126: λExpressions 
Solution
–Simple syntactic sugar
–Set of functionalinterfaces –Libraries using these interfaces
http://blog.orfjackal.net/2014/07/java-8-functional-int erface-naming-guide.html

83/466
JSR-335, JEP-126: λExpressions 
Solution
–Simple syntactic sugar
–Set of functionalinterfaces
–Libraries using these interfaces
https://blogs.oracle.com/javamagazine/post/functional-progr amming-in-java-part-1-lists-lambdas-and-method-refere nces

84/466
JSR-335, JEP-126: λExpressions 
Solution
–Simple syntactic sugar
–Set of functionalinterfaces
–Libraries using these interfaces
https://blogs.oracle.com/javamagazine/post/functional-progr amming-in-java-part-1-lists-lambdas-and-method-refere nces 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>
namesStartingWithR
=
friends
.stream().
filter(
name
->
name
.startsWith(
"R"
)).collect(Collectors.toList());
System.
out
.println(
namesStartingWithR
);

85/466
JSR-335, JEP-126: λExpressions 
But code duplication!
https://blogs.oracle.com/javamagazine/post/functional-progr amming-
in-java-part-2-lambda-reuse-lexical-scoping-and-closures-a nd-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.

86/466
JSR-335, JEP-126: λExpressions 
But code duplication!
https://blogs.oracle.com/javamagazine/post/functional-progr amming-
in-java-part-2-lambda-reuse-lexical-scoping-and-closures-a nd-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.

87/466
JSR-335, JEP-126: λExpressions 
But code duplication!
https://blogs.oracle.com/javamagazine/post/functional-progr amming-
in-java-part-2-lambda-reuse-lexical-scoping-and-closures-a nd-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.

88/466
JSR-335, JEP-126: λExpressions 
But code duplication!
https://forum.devtalk.com/t/functional-programming-in-ja va-second-
edition-p-35-refactoring-to-narrow-the-scope-code/10544 7
// 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.

89/466
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
);
}
}

90/466
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
);
}
}

91/466
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

92/466
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

93/466
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
);
}
}
}

94/466
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 '@NonNullString'

95/466
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/

96/466
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)"
);
}
}
}

97/466
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/

98/466
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/

99/466
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
);
}
}

100/466
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")

101/466
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
);
}
}

102/466
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

103/466
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
);
}
}

104/466
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")})

105/466
JVM

106/466
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

107/466
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

108/466
APIS

109/466
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

110/466
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
);

111/466
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.*

112/466
MISC

113/466
JEP-153: JavaFX Applications 
Three “types” of programs
–Class files
–JAR files
–JavaFX

Enhance the javacommand-line to launch
JavaFX programs

114/466
Java 9
2017/09/21

115/466
LANGUAGE

116/466
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());
}

117/466
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

118/466
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/

119/466
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

120/466
JSR-376: Modularization 
Classpath / JARs Hell

Version conflicts

Large Monolithic JDK

Security Problems
https://www.geeksforgeeks.org/jpms-java-platform-module-system/

121/466
JSR-376: Modularization 
Classpath/ JARs Hell

Version conflicts
–Cf. DLL Hell, no versions, one directory
–One, longlist 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/

122/466
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/

123/466
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/

124/466
JSR-376: Modularization

125/466
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

126/466
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;
}

127/466
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;
}

128/466
JSR-376: Modularization

Declaration of module com.example.foo

Dependencies on
three other modules
– transitive: client
modules also can
access thatmodule
– 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;
}

129/466
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;
}

130/466
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.networkor
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;
}

131/466
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

132/466
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

133/466
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!)

134/466
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

135/466
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
...

136/466
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

137/466
JSR-376: Modularization

Client

Provider
module
ModularizationWithModulesClient1 {
requires
ModularizationWithModulesLibrary1;
}
module
ModularizationWithModulesLibrary1 {
exports
net.ptidej.modularisation.kernel;
exports
net.ptidej.modularisation.kernel.impl;
}

138/466
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

139/466
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

140/466
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

141/466
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;
}

142/466
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();

143/466
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();

144/466
JSR-376: Modularization 
Accessibility
–Observability
–Readability
• requiresvs. requires transitive
–Visibility
• publicvs. “default”
Problem: How to decide what packages and
types are accessible?
Solution: Readability vs. Visibility

145/466
JSR-376: Modularization 
Accessibility (bis)
–Compile-time, run-time:
--add-exports
• Access to public types not exported via the module
descriptor, for compilation and execution
–Run-time only:
--add-opens
• Access to all types not exported via the module
descriptor through reflection (cf. setAccessible())

146/466
JSR-376: Modularization
https://www.baeldung.com/java-illegal-reflective-access

Backward compatibility

Automatic module name
–Classpathvs. Module path
–JAR found on the module path

147/466
JSR-376: Modularization
https://medium.com/@dvsingh9/java-modules-a-complete-guide-part-2-340e5b8d26

148/466
JSR-376: Modularization
https://docs.oracle.com/javase%2F9%2Fdocs%2Fapi%2F%2F/overview-summary.html

149/466
JSR-376: Modularization
https://docs.oracle.com/javase%2F9%2Fdocs%2Fapi%2F%2F/java/lang/Module.html

150/466
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
•Modularprograms and libraries
• IoT and other constrained devices
https://www.techtarget.com/searchnetworking/definition/OS Gi

151/466
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-modulari ty/, https://www.infoq.com/articles/java9-osgi-future-mod ularity-
part-2/, https://www.baeldung.com/java-illegal-reflecti ve-access, https://en.wikipedia.org/wiki/OSGi

152/466
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-modulari ty/, https://www.infoq.com/articles/java9-osgi-future-mod ularity-
part-2/, https://www.baeldung.com/java-illegal-reflecti ve-access, https://en.wikipedia.org/wiki/OSGi

153/466
JEP-213: Milling Project Coin 
From Java 7
– Allow @SafeVargson private instance methods
– Allow effectively-finalvariables 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

154/466
JVM

155/466

Nothing to mention, so much
work went into modularisation

156/466
APIS

157/466
Collection Factory Methods 
No nullvalues

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"
);
}
}

158/466
Collection Factory Methods 
No nullvalues

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
)

159/466
JavaDB Removal 
JavaDB was a repackaging of Apache Derby
–Relational database
–Open-source
–Entirely in Java
–Embedded JDBC driver

160/466
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) orUTF-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

161/466
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-l ooks-tiny-on-high-dpi-screen-when-it-should-be-scaled-to- normal

162/466
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
));

163/466
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>

164/466
MISC

165/466
JEP-222: jshell

166/466
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 \
net\ptidej\newjava\jlink\HelloWorld.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

167/466
JEP-295: jaotc 
Ahead-of-time compilation
–Compile Java classes to native code
beforelaunching 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

168/466
Java 10
2018/03/20

169/466
LANGUAGE

170/466
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.

171/466
JVM

172/466
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;
// ...

173/466
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/

174/466
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

175/466
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>

176/466
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-in tro-to-nvdimm-n/
-XX:AllocateHeapAt=<path>

177/466
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

178/466
APIS

179/466
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

180/466
MISC

181/466
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
...

182/466
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
...

183/466
JEP-313: Native-Header Generation
Tool Removal

javahfeatures (and more) now in javac
javac HelloWorld.java
javah HelloWorld
javac -h jni -d bin HelloWorld.java
vs.

184/466
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

185/466
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());

186/466
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

187/466
Java 11
2018/09/25

188/466
LANGUAGE

189/466
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();
}
}

190/466
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
);
}
}
}

191/466
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

192/466
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"
));
}
}

193/466
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

194/466
JVM

195/466
JEP-309: Dynamic .classConstants 
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

196/466
JEP-309: Dynamic .classConstants
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"
);
}
}

197/466
JEP-309: Dynamic .classConstants
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
;
}
}

198/466
JEP-309: Dynamic .classConstants
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.

199/466
JEP-309: Dynamic .classConstants
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

200/466
JEP-309: Dynamic .classConstants 
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

201/466
JEP-309: Dynamic .classConstants 
Dynamic constants, javacvs. 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

202/466
JEP-309: Dynamic .classConstants 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());

203/466
JEP-309: Dynamic .classConstants 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

204/466
JEP-309: Dynamic .classConstants 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

205/466
JEP-309: Dynamic .classConstants 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
SomExpensiveDatacreated
only once, with first call()

206/466
JEP-309: Dynamic .classConstants 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

207/466
JEP-309: Dynamic .classConstants 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

208/466
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

209/466
JEP-331: Low-overhead Heap
Profiling
https://docs.dynatrace.com/docs/platform-modules/application s-and-microservices/profiling-and-optimization/memory-pro filing

210/466
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

211/466
APIS

212/466
JEP-320: Java EE and CORBA
Modules Removal

Since Java 1.2
– OMG CORBA API
– ORB implementation
– CosNaming implementation
– idljcompiler
– Support for IDL and IIOP in rmiccompiler
–No significant interest in CORBA anymore

Since Java 6
– Full Web Services stack
–Now available from third parties

Deprecated in Java 9

213/466
JEP-321: HTTP Client 
Problems with HttpURLConnectionAPI
–Designed for (now dead) protocols (gopher…)
–Designed before HTTP/1.1
–Too abstract
–Hard to use
–Badly documented
–Blocking mode only
–Very hard maintenance

214/466
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

215/466
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());

216/466
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"
}

217/466
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

218/466
JEP-335: Nashorn Deprecation 
Since Java 8
–JEP-174

ECMAScript changes rapidly
–Language
–APIs

Maintenance challenges
–Deprecate Nashorn, its APIs, and
jjs

219/466
MISC

220/466
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-monitorin g
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
-XX:StartFlightRecording=duration=200s,filename=flight.jfr

221/466
JEP-328: Flight Recorder
https://www.baeldung.com/java-flight-recorder-monitorin g

222/466
JEP-330: Single-file Source-code
Programs Launching

Lower the (early) learning curve
–But no dependency management
java –cp some.jar HelloWorld.java

223/466
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

224/466
Java 12
2019/03/19

225/466
LANGUAGE

226/466

Nothing to mention?

227/466
JVM

228/466
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-th e-jdks-new-superfast-garbage-collectors
-XX:G1MixedGCCountTarget=<number of mixed garbage collections>

229/466
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>

230/466
APIS

231/466
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-highli ghts-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
);
}
}

232/466
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-highli ghts-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]

233/466
MISC

234/466
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

235/466
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

236/466
JEP-230: Microbenchmark Suite 
Run one java.util.UUIDBenchbenchmark
– 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-Over heads.html
make test TEST=micro:UUIDBench.fromType3Bytes

237/466
JEP-230: Microbenchmark Suite 
Run one java.util.UUIDBenchbenchmark
– 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-Over heads.html
make test TEST=micro:UUIDBench.fromType3Bytes
Benchmark Score Error Units
fromType3Bytes 1.460 ±0.089 ops/us

238/466
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/archit ect-benchmarking.html

239/466
Java 13
2019/09/17 2019/09/17 2019/09/17 2019/09/17

240/466
LANGUAGE

241/466

Nothing to mention?

242/466
JVM

243/466
JEP-351: Unused Memory
Uncommit

ZGC automatically returns heap memory to
the operating system when idle
–Cf. JEP-346
-XX:ZUncommitDelay=<seconds>

244/466
APIS

245/466
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

246/466
MISC

247/466

Nothing to mention?

248/466
Java 14
2020/03/17

249/466
LANGUAGE

250/466
-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();
}
}

251/466
-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
)

252/466
-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
)

253/466
JEP-361: switchExpressions
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
;
}

254/466
JVM

255/466
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>

256/466
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

257/466
JEP-363: Concurrent Mark Sweep
GC Removal

Since Java 9
–Deprecated CMS

Reduce maintenance costs
–Replaced by G1
–Two new GCs
• ZGC
• Shenandoah

258/466
APIS

259/466
JEP-352: Non-volatile Mapped Byte
Buffers

FileChannelcan create MappedByteBuffer
that access non-volatile memory
–Cf. JEP-316
https://mashona.io/blog/2020/03/17/using-jep-352-api
final
File
file
=
new
File(
"/path/to/some/file"
);
final
FileChannel
fileChannel
= (FileChannel) Files.newByteChannel(
file
.toPath(),
EnumSet.of(StandardOpenOption.
READ
,
StandardOpenOption.
WRITE
,
StandardOpenOption.
CREATE
));
try
{final
MappedByteBuffer
mappedByteBuffer
=
fileChannel
.map(MapMode.
READ_WRITE
, position, size);
// ...
}
catch
(
final
IOException
e
) {
// ...
}

260/466
MISC

261/466
JEP-349: JFR Event Streaming 
API for the streaming of JFR data
–In-process, out-of-process programs
–Cf. JEP-328

Example: Health Report
https://blogs.oracle.com/javamagazine/post/java-flight-recor der-and-jfr-event-streaming-in-java-14
https://github.com/flight-recorder/health-report
java -javaagent:health-report.jar com.example.MyProgram

262/466
JEP-349: JFR Event Streaming 
Example: Health Report
https://blogs.oracle.com/javamagazine/post/java-flight-recor der-and-jfr-event-streaming-in-java-14
https://github.com/flight-recorder/health-report
=================== HEALTH REPORT === 2021-05-13 23:57:50 ====================
| GC: G1Old/G1New Phys. memory: 28669 MB Alloc Rate: 8 MB/s |
| OC Count : 28 Initial Heap: 448 MB Total Alloc: 190 MB |
| OC Pause Avg: 40.1 ms Used Heap : 19 MB Thread Count: 20.0 |
| OC Pause Max: 48.8 ms Commit. Heap: 47 MB Class Count : 3894.0 |
| YC Count : 8 CPU Machine : 20.12 % Safepoints: 335 |
| YC Pause Avg: 5.7 ms CPU JVM User : 10.28 % Max Safepoint: 46.4 ms |
| YC Pause Max: 22.4 ms CPU JVM System: 1.07 % Max Comp. Time: 728.3 ms |
|--- Top Allocation Methods ------------------------------- -----------------|
| DataBufferInt.(int) 11.27 % |
| Component.size() 9.01 % |
| BufferedContext.validate(...) 6.21 % |
| Path2D$Double.(...) 5.87 % |
| SunGraphics2D.clone() 5.85 % |
|--- Hot Methods ------------------------------------------------------------|
| DRenderer._endRendering(int, int) 51.11 % |
| DRenderer.copyAARow(...) 6.67 % |
| Arrays.fill(...) 4.44 % |
| StringConcatFactory.doStringConcat(...) 2.22 % |
| MarlinTileGenerator.getAlphaNoRLE(...) 2.22 % |
==============================================================================

263/466
Java 15
2020/09/15

264/466
LANGUAGE

265/466
JEP-371: Hidden Classes 
Classes
– Member classes

Methods
– Inner classes
– Anonymous classes
– Lambda expressions

Encapsulation

Reflection

266/466
JEP-371: Hidden Classes 
Hidden classes
–Dynamic class creation (and their instances)
–Classes that are not publicly visible/accessible

Improve
–Encapsulation
• Internal implementations
–Security
• Risk of unauthorized access (or tampering)
https://www.javacodegeeks.com/2024/02/explore-java-15s-hidden-classes-with-code-examples.html

267/466
JEP-371: Hidden Classes class
TopLevelClass {
public class
MemberClass {
}
}
public class
Example1 {
public static void
main(
final
String[]
args
)
throws
ClassNotFoundException {
class
InnerClass {
}
final
InnerClass
innerClass
=
new
InnerClass();
final
Callable<String>
anonynmousClass
=
new
Callable<String>() {
@Override public
String call()
throws
Exception {
return null
; }};
final
Callable<String>
lambdaExpression
= () ->
null
;
final
Class<?>
classOfClazz
= Class.forName(
"[...].TopLevelClass"
);
InfoPrinter.printInfo(
classOfClazz
);
final
Class<?>
classOfMemberClass
= Class.forName(
"[...].TopLevelClass$MemberClass"
);
InfoPrinter.printInfo(
classOfMemberClass
);
final
Class<?>
classOfInnerClass
=
innerClass
.getClass();
// final Class<?> classOfInnerClass = Class.forName("
[...]
.Example1$1InnerClass");
InfoPrinter.printInfo(
classOfInnerClass
);
final
Class<?>
classOfAnonymousClass
=
anonynmousClass
.getClass();
// final Class<?> classOfAnonymousClass = Class.forName("
[...]
.Example1$1");
InfoPrinter.printInfo(
classOfAnonymousClass
);
final
Class<?>
classOfLambdaExpression
=
lambdaExpression
.getClass();
// final Class<?> classOfLambdaExpression = Class.forName("
[...]
.Example1$$Lambda/???");
InfoPrinter.printInfo(
classOfLambdaExpression
);
}
}

268/466
JEP-371: Hidden Classes class
TopLevelClass {
public class
MemberClass {
}
}
public class
Example1 {
public static void
main(
final
String[]
args
)
throws
ClassNotFoundException {
class
InnerClass {
}
final
InnerClass
innerClass
=
new
InnerClass();
final
Callable<String>
anonynmousClass
=
new
Callable<String>() {
@Override public
String call()
throws
Exception {
return null
; }};
final
Callable<String>
lambdaExpression
= () ->
null
;
final
Class<?>
classOfClazz
= Class.forName(
"[...].TopLevelClass"
);
InfoPrinter.printInfo(
classOfClazz
);
final
Class<?>
classOfMemberClass
= Class.forName(
"[...].TopLevelClass$MemberClass"
);
InfoPrinter.printInfo(
classOfMemberClass
);
final
Class<?>
classOfInnerClass
=
innerClass
.getClass();
// final Class<?> classOfInnerClass = Class.forName("
[...]
.Example1$1InnerClass");
InfoPrinter.printInfo(
classOfInnerClass
);
final
Class<?>
classOfAnonymousClass
=
anonynmousClass
.getClass();
// final Class<?> classOfAnonymousClass = Class.forName("
[...]
.Example1$1");
InfoPrinter.printInfo(
classOfAnonymousClass
);
final
Class<?>
classOfLambdaExpression
=
lambdaExpression
.getClass();
// final Class<?> classOfLambdaExpression = Class.forName("
[...]
.Example1$$Lambda/???");
InfoPrinter.printInfo(
classOfLambdaExpression
);
}
}
class net.ptidej.newjava.hiddenclasses.TopLevelClass
Canonical name: net.ptidej.newjava.hiddenclasses.TopLevelClass
Name: net.ptidej.newjava.hiddenclasses.TopLevelClass
isHidden? false
class net.ptidej.newjava.hiddenclasses.TopLevelClass$MemberClass
Canonical name: net.ptidej.newjava.hiddenclasses.TopLevelClass.MemberClass
Name: net.ptidej.newjava.hiddenclasses.TopLevelClass$MemberClass
isHidden? false
class net.ptidej.newjava.hiddenclasses.Example1$1InnerClass
Canonical name: null
Name: net.ptidej.newjava.hiddenclasses.Example1$1InnerClass
isHidden? false
class net.ptidej.newjava.hiddenclasses.Example1$1
Canonical name: null
Name: net.ptidej.newjava.hiddenclasses.Example1$1
isHidden? false
class net.ptidej.newjava.hiddenclasses.Example1$$Lambda/0x0000020a81000400
Canonical name: null
Name: net.ptidej.newjava.hiddenclasses.Example1$$Lambda/0x0000020a81000400
isHidden? true

269/466
JEP-371: Hidden Classes class
TopLevelClass {
public class
MemberClass {
}
}
public class
Example1 {
public static void
main(
final
String[]
args
)
throws
ClassNotFoundException {
class
InnerClass {
}
final
InnerClass
innerClass
=
new
InnerClass();
final
Callable<String>
anonynmousClass
=
new
Callable<String>() {
@Override public
String call()
throws
Exception {
return null
; }};
final
Callable<String>
lambdaExpression
= () ->
null
;
final
Class<?>
classOfClazz
= Class.forName(
"[...].TopLevelClass"
);
InfoPrinter.printInfo(
classOfClazz
);
final
Class<?>
classOfMemberClass
= Class.forName(
"[...].TopLevelClass$MemberClass"
);
InfoPrinter.printInfo(
classOfMemberClass
);
final
Class<?>
classOfInnerClass
=
innerClass
.getClass();
// final Class<?> classOfInnerClass = Class.forName("
[...]
.Example1$1InnerClass");
InfoPrinter.printInfo(
classOfInnerClass
);
final
Class<?>
classOfAnonymousClass
=
anonynmousClass
.getClass();
// final Class<?> classOfAnonymousClass = Class.forName("
[...]
.Example1$1");
InfoPrinter.printInfo(
classOfAnonymousClass
);
final
Class<?>
classOfLambdaExpression
=
lambdaExpression
.getClass();
// final Class<?> classOfLambdaExpression = Class.forName("
[...]
.Example1$$Lambda/???");
InfoPrinter.printInfo(
classOfLambdaExpression
);
}
}
class net.ptidej.newjava.hiddenclasses.TopLevelClass
Canonical name: net.ptidej.newjava.hiddenclasses.TopLevelClass
Name: net.ptidej.newjava.hiddenclasses.TopLevelClass
isHidden? false
class net.ptidej.newjava.hiddenclasses.TopLevelClass$MemberClass
Canonical name: net.ptidej.newjava.hiddenclasses.TopLevelClass.MemberClass
Name: net.ptidej.newjava.hiddenclasses.TopLevelClass$MemberClass
isHidden? false
class net.ptidej.newjava.hiddenclasses.Example1$1InnerClass
Canonical name: null
Name: net.ptidej.newjava.hiddenclasses.Example1$1InnerClass
isHidden? false
class net.ptidej.newjava.hiddenclasses.Example1$1
Canonical name: null
Name: net.ptidej.newjava.hiddenclasses.Example1$1
isHidden? false
class net.ptidej.newjava.hiddenclasses.Example1$$Lambda/0x0000020a81000400
Canonical name: null
Name: net.ptidej.newjava.hiddenclasses.Example1$$Lambda/0x0000020a81000400
isHidden? true
Hidden class

270/466
JEP-371: Hidden Classes 
Use and features of hidden classes
final
InputStream
stream
=
new
FileInputStream(
new
File(
"rsc/HiddenClass.class"
));
final byte
[]
bytes
= IOUtils.toByteArray(
stream
);
final
MethodHandles.Lookup
lookup
= MethodHandles.lookup();
final
Class<?>
hiddenClassClass1
=
lookup
.defineHiddenClass(
bytes
,
true
,
STRONG
).lookupClass();
InfoPrinter.printInfo(
hiddenClassClass1
);
final
Class<?>
notHiddenClassClass1
=
lookup
.defineClass(
bytes
);
InfoPrinter.printInfo(
notHiddenClassClass1
);
final
Class<?>
notHiddenClassClass2
=
myClassLoader
.loadClass(
"[...].HiddenClass"
,
bytes
);
InfoPrinter.printInfo(
notHiddenClassClass2
);
final
Class<?>
hiddenClassClass2
= Class.forName(
hiddenClassClass1
.getName());
InfoPrinter.printInfo(
hiddenClassClass2
);
final
Class<?>
hiddenClassClass3
=
lookup
.findClass(
hiddenClassClass1
.getName());
InfoPrinter.printInfo(
hiddenClassClass3
);

271/466
JEP-371: Hidden Classes 
Use and features of hidden classes
final
InputStream
stream
=
new
FileInputStream(
new
File(
"rsc/HiddenClass.class"
));
final byte
[]
bytes
= IOUtils.toByteArray(
stream
);
final
MethodHandles.Lookup
lookup
= MethodHandles.lookup();
final
Class<?>
hiddenClassClass1
=
lookup
.defineHiddenClass(
bytes
,
true
,
STRONG
).lookupClass();
InfoPrinter.printInfo(
hiddenClassClass1
);
final
Class<?>
notHiddenClassClass1
=
lookup
.defineClass(
bytes
);
InfoPrinter.printInfo(
notHiddenClassClass1
);
final
Class<?>
notHiddenClassClass2
=
myClassLoader
.loadClass(
"[...].HiddenClass"
,
bytes
);
InfoPrinter.printInfo(
notHiddenClassClass2
);
final
Class<?>
hiddenClassClass2
= Class.forName(
hiddenClassClass1
.getName());
InfoPrinter.printInfo(
hiddenClassClass2
);
final
Class<?>
hiddenClassClass3
=
lookup
.findClass(
hiddenClassClass1
.getName());
InfoPrinter.printInfo(
hiddenClassClass3
);
class net.ptidej.newjava.hiddenclasses.HiddenClass/0x000001e2900082b0
Canonical name: null
Name: net.ptidej.newjava.hiddenclasses.HiddenClass/0x000001e2900082b0
isHidden? true
class net.ptidej.newjava.hiddenclasses.HiddenClass
Canonical name: net.ptidej.newjava.hiddenclasses.HiddenClass
Name: net.ptidej.newjava.hiddenclasses.HiddenClass
isHidden? false
class net.ptidej.newjava.hiddenclasses.HiddenClass
Canonical name: net.ptidej.newjava.hiddenclasses.HiddenClass
Name: net.ptidej.newjava.hiddenclasses.HiddenClass
isHidden? false
As expected, the hidden class cannot be discovered!
As expected, the hidden class cannot be discovered!

272/466
JEP-371: Hidden Classes 
Use and features of hidden classes
final
InputStream
stream
=
new
FileInputStream(
new
File(
"rsc/HiddenClass.class"
));
final byte
[]
bytes
= IOUtils.toByteArray(
stream
);
final
MethodHandles.Lookup
lookup
= MethodHandles.lookup();
final
Class<?>
hiddenClassClass1
=
lookup
.defineHiddenClass(
bytes
,
true
,
STRONG
).lookupClass();
InfoPrinter.printInfo(
hiddenClassClass1
);
final
Class<?>
notHiddenClassClass1
=
lookup
.defineClass(
bytes
);
InfoPrinter.printInfo(
notHiddenClassClass1
);
final
Class<?>
notHiddenClassClass2
=
myClassLoader
.loadClass(
"[...].HiddenClass"
,
bytes
);
InfoPrinter.printInfo(
notHiddenClassClass2
);
final
Class<?>
hiddenClassClass2
= Class.forName(
hiddenClassClass1
.getName());
InfoPrinter.printInfo(
hiddenClassClass2
);
final
Class<?>
hiddenClassClass3
=
lookup
.findClass(
hiddenClassClass1
.getName());
InfoPrinter.printInfo(
hiddenClassClass3
);
class net.ptidej.newjava.hiddenclasses.HiddenClass/0x000001e2900082b0
Canonical name: null
Name: net.ptidej.newjava.hiddenclasses.HiddenClass/0x000001e2900082b0
isHidden? true
class net.ptidej.newjava.hiddenclasses.HiddenClass
Canonical name: net.ptidej.newjava.hiddenclasses.HiddenClass
Name: net.ptidej.newjava.hiddenclasses.HiddenClass
isHidden? false
class net.ptidej.newjava.hiddenclasses.HiddenClass
Canonical name: net.ptidej.newjava.hiddenclasses.HiddenClass
Name: net.ptidej.newjava.hiddenclasses.HiddenClass
isHidden? false
As expected, the hidden class cannot be discovered!
As expected, the hidden class cannot be discovered!
Hidden classes
are truly hidden

273/466
JEP-378: Text Blocks 
Multi-line string literal
–C++
• Compiler concatenates adjacent string literals
• Escape embedded (invisible) newline chars
–JavaScript
• Template literals with `(backtick)
–Python
• Use """

274/466
JEP-378: Text Blocks 
Three quotes
–Followed by white space(s)
–Followedbya new line!
final
String
textBlock
=
"""
Hello
World!"""
;
System.
out
.println(
textBlock
);

275/466
JEP-378: Text Blocks 
Three quotes
–Followed by white space(s)
–Followedbya new line!
final
String
textBlock
=
"""
Hello
World!"""
;
System.
out
.println(
textBlock
);
Hello
World!

276/466
JVM

277/466
JEP-377: Scalable Low-latency GC 
Since Java 11
–Pause times not exceeding 10ms
• With 2 MB or 2 TB heaps
–Cf. JEP-333 
ZGC becomes a product feature
-XX:+UnlockExperimentalVMOptions
-XX:+UseZGC

278/466
JEP-379: Low-pause-time GC 
Since Java 12
–Consistent pause times
• With 200 MB or 200 GB heaps
–Cf. JEP-189 
Shenandoah becomes a product feature
XX:+UnlockExperimentalVMOptions
-XX:+UseShenandoahGC

279/466
APIS

280/466
JEP-373: Legacy DatagramSocket
API Reimplementation

Reimplementations
– java.net.DatagramSocket
– java.net.MulticastSocket 
Since Java 1.0!

Concurrency issues

No clean support of IPv6

Mix of legacy Java and C code

281/466
JEP-385: RMI Object Activation
Deprecation

Since Java 1.1
–Remote Method Invocation

Since Java 1.2
–A remote object can be made persistent
and later activated into a liveobject

Since Java 8
–Optional
–Obsolete
• Security

282/466
MISC

283/466

Nothing to mention?

284/466
Java 16
2021/03/16

285/466
LANGUAGE

286/466
JEP-390: Warnings for Value-based
Classes

Value-based Classes
–Marked with the
final
modifier
–Equal solely based on equals()
–Freely substitutable when equal
–Instantiated via factory methods

With @ValueBased
–Warning with identity-sensitive operations
•Synchronisation, identity hashing, serialization…
https://dzone.com/articles/moving-toward-inline-classes-jep- 390-and-the-value

287/466
JEP-394: Pattern Matching for
instanceof

Testing if an expression is of a type and
conditionally extracting components
https://openjdk.org/jeps/394
final
Object
o1
= Integer.valueOf(1);
if
(
o1
instanceof
Integer) {
final
Integer
integer
= (Integer)
o1
;
System.
out
.println(
integer
.intValue());
}
public final boolean
equals1(
final
Object
o
) {
return
(
o
instanceof
String)
&& ((String)
o
).equalsIgnoreCase(
string
);
}

288/466
JEP-394: Pattern Matching for
instanceof

Testing if an expression is of a type and
conditionally extracting components
https://openjdk.org/jeps/394
final
Object
o1
= Integer.valueOf(1);
if
(
o1
instanceof
Integer) {
final
Integer
integer
= (Integer)
o1
;
System.
out
.println(
integer
.intValue());
}
public final boolean
equals1(
final
Object
o
) {
return
(
o
instanceof
String)
&& ((String)
o
).equalsIgnoreCase(
string
);
}
final
Object
o3
= Integer.valueOf(3);
if
(
o3
instanceof
Integer
integer
) {
System.
out
.println(
integer
.intValue());
}
public final boolean
equals2(
final
Object
o
) {
return
(
o
instanceof
String
s
)
&&
s
.equalsIgnoreCase(
string
);
}

289/466
JEP-395: Records 
Nominal tuples, with immutable data
– private final –No setters
https://www.baeldung.com/java-record-keyword
record
Person(String
firstName
, String
lastName
) {
}
// ... final
Person
person1
=
new
Person(
"Rick"
,
"Deckard"
);
System.
out
.println(
person1
);
final
Person
person2
=
new
Person(
"Rick"
,
"Deckard"
);
System.
out
.println(
person2
);
final
Person
person3
=
new
Person(
"Roy"
,
"Batty"
);
System.
out
.println(
person3
);
System.
out
.print(
person1
.firstName());
System.
out
.println(
person1
.equals(
person2
));
System.
out
.println(
person1
.equals(
person3
));
final
Class<?>
clazz
= Class.forName(
"[...].Person"
);
final
Field
field
=
clazz
.getDeclaredField(
"firstName"
);
field
.set(
person1
,
"Leon"
);

290/466
JEP-395: Records 
Nominal tuples, with immutable data
– private final –No setters
https://www.baeldung.com/java-record-keyword
record
Person(String
firstName
, String
lastName
) {
}
// ... final
Person
person1
=
new
Person(
"Rick"
,
"Deckard"
);
System.
out
.println(
person1
);
final
Person
person2
=
new
Person(
"Rick"
,
"Deckard"
);
System.
out
.println(
person2
);
final
Person
person3
=
new
Person(
"Roy"
,
"Batty"
);
System.
out
.println(
person3
);
System.
out
.print(
person1
.firstName());
System.
out
.println(
person1
.equals(
person2
));
System.
out
.println(
person1
.equals(
person3
));
final
Class<?>
clazz
= Class.forName(
"[...].Person"
);
final
Field
field
=
clazz
.getDeclaredField(
"firstName"
);
field
.set(
person1
,
"Leon"
);
IllegalAccessException

291/466
JVM

292/466
JEP-347: C++14 Language Features 
Use of C++14 in JDK C++ source code
–Since Java 11
• C++updated for recent C++ compilers
–Until Java 15
• C++98/03

Specifics depend on the compiler
/std:c++14
-std=c++14

293/466
JEP-376: Concurrent Thread-stack
Processing

ZGC thread-stack processing
–From safepoints to concurrent

Remove GC pauses and scalability issues

Make pauses sub-milliseconds

294/466
APIS

295/466

Nothing to mention?

296/466
MISC

297/466
JEP-392: Packaging Tool 
Since Java 14
–Native Java installer generator
–Cf. JEP-343

From WORA to WORADA
–Write Once, Run Anywhere
–Write Once, Run Anywhere, Deploy Anywhere
https://jfrog.com/blog/java-artifacts-just-got-better-jp ackage-is-production-ready-in-java-16/

298/466
JEP-392: Packaging Tool 
Without JRE

With (some of the) JRE
–Cf. JSR-376
https://jfrog.com/blog/java-artifacts-just-got-better-jp ackage-is-production-ready-in-java-16/
jpackage --name myprog --input lib
--main-jar main.jar
--main-class my.program.Main
jlink --add-modules java.base,java.sql --output smalljre
jpackage --name myprog --input lib
--main-jar main.jar
--main-class my.program.Main
--runtime-image smalljre

299/466
Java 17
2021/09/14

300/466
LANGUAGE

301/466
JEP-306: Always-strict Floating -
point Semantics Restoration

Consistently strict floating -point operations

Before
–Platform-dependent floating-point
representations, computations

Now
–IEEE Standard for Floating Point Arithmetic
• IEEE 754
–Warnings for unnecessary use of
strictfp

302/466
JEP-409: Sealed Classes 
Fine-grain control
on subclassing
– final
– sealed
• permits
– non-sealed
sealed class
Person
permits
Employee, Student, Instructor {
}
final class
Employee
extends
Person {
}
sealed class
Student
extends
Person
permits
Bacc, Grad {
}
final class
Bacc
extends
Student {
}
final class
Grad
extends
Student {
}
non-sealed class
Instructor
extends
Person {
}
class
LTA
extends
Instructor {
}
class
ETA
extends
Instructor {
}
class
Prof
extends
Instructor {
}
// ...
*
https://www.reddit.com/r/java/comments/inol55/does_anyone_else_not_like_the_nonsealed_keyword/
but read also https://openjdk.org/jeps/8223002

303/466
JEP-409: Sealed Classes 
Fine-grain control
on subclassing
– final
– sealed
• permits
– non-sealed
sealed class
Person
permits
Employee, Student, Instructor {
}
final class
Employee
extends
Person {
}
sealed class
Student
extends
Person
permits
Bacc, Grad {
}
final class
Bacc
extends
Student {
}
final class
Grad
extends
Student {
}
non-sealed class
Instructor
extends
Person {
}
class
LTA
extends
Instructor {
}
class
ETA
extends
Instructor {
}
class
Prof
extends
Instructor {
}
// ...
Ugly because
negative and
hyphenated
*
*
https://www.reddit.com/r/java/comments/inol55/does_anyone_else_not_like_the_nonsealed_keyword/
but read also https://openjdk.org/jeps/8223002

304/466
JVM

305/466

Nothing to mention?

306/466
APIS

307/466
JEP-356: Enhanced Pseudo-random
Number Generators
https://www.baeldung.com/java-17-random-number-generators

308/466
JEP-356: Enhanced Pseudo-random
Number Generators

Beware of thread-safety!
RandomGeneratorFactory.all().sorted(
Comparator.comparing(RandomGeneratorFactory::name))
.forEach(
factory
-> System.
out
.println(
String.format(
"%s\t%s\t%s\t%s"
,
factory
.group(),
factory
.name(),
factory
.isJumpable(),
factory
.isSplittable())));
final
RandomGenerator
generator
= RandomGenerator.getDefault();
System.
out
.println(
generator
.nextInt());

309/466
JEP-398: Applet API Deprecation 
No more support in Web browsers

Deprecated for removal
– java.applet.Applet
– java.applet.AppletStub
– java.applet.AppletContext
– java.applet.AudioClip
– javax.swing.JApplet
– java.beans.AppletInitializer

310/466
JEP-415: Context-specific
Deserialization Filters

Context-specific, dynamically-selected
deserialization filters
-Djdk.serialFilter=net.ptidej.newjava.*;!*
final
ObjectInputFilter
filter
=
ObjectInputFilter.Config.createFilter(
"net.ptidej.newjava.*;!*"
);
ObjectInputFilter.Config.setSerialFilter(
filter
);
OR

311/466
MISC

312/466

Nothing to mention?

313/466
Java 18
2022/03/22

314/466
LANGUAGE

315/466
JEP-421: Finalization
Deprecation

Since Java 1.0
– finalize()
method
–E.g., in Caffeine (ASE’02)

Deprecation, disable, removal

Should be replaced with
– try
with resources
• Cf. Java 7
–Cleaners

316/466
JEP-421: Finalization
Deprecation

Since Java 9
– java.lang.ref.Cleaner –Cleanup actions for groups of objects
https://howtodoinjava.com/java/basics/java-cleaners/
public static void
main(
final
String[]
args
)
throws
Exception {
try
(
final
ResourceAccessingClass
o
=
new
ResourceAccessingClass()) {
// Safely use the resource o
.businessOperation1();
o
.businessOperation2();
}
}

317/466
JEP-421: Finalization
Deprecation

Since Java 9
– java.lang.ref.Cleaner –Cleanup actions for groups of objects
https://howtodoinjava.com/java/basics/java-cleaners/
public static void
main(
final
String[]
args
)
throws
Exception {
try
(
final
ResourceAccessingClass
o
=
new
ResourceAccessingClass()) {
// Safely use the resource o
.businessOperation1();
o
.businessOperation2();
}
}
Inside businessOperation1() with [...].Resource@65b54208
Inside businessOperation2() with [...].Resource@65b54208
Resource cleaned up

318/466
JEP-421: Finalization
Deprecation
class
Resource {
// Some (expensive) resource
}class
ResourceAccessingClass
implements
AutoCloseable {
private final
Cleaner
cleaner
= Example1.getCleaner();
private final
Cleaner.Cleanable
cleanable
;
private final
Resource
resource
;
public
ResourceAccessingClass() {
this
.
resource
=
new
Resource();
this
.
cleanable
=
cleaner
.register(
this
, () -> {
System.
out
.println(
"Resource cleaned up"
);});
}
public void
businessOperation1() {
System.
out
.print(
"Inside businessOperation1() with "
);
System.
out
.println(
this
.
resource
);
}
// ...
https://howtodoinjava.com/java/basics/java-cleaners/

319/466
JEP-421: Finalization
Deprecation
class
Resource {
// Some (expensive) resource
}class
ResourceAccessingClass
implements
AutoCloseable {
private final
Cleaner
cleaner
= Example1.getCleaner();
private final
Cleaner.Cleanable
cleanable
;
private final
Resource
resource
;
public
ResourceAccessingClass() {
this
.
resource
=
new
Resource();
this
.
cleanable
=
cleaner
.register(
this
, () -> {
System.
out
.println(
"Resource cleaned up"
);});
}
public void
businessOperation1() {
System.
out
.print(
"Inside businessOperation1() with "
);
System.
out
.println(
this
.
resource
);
}
// ...
https://howtodoinjava.com/java/basics/java-cleaners/
Register a Cleanable
to
clean asynchronously

320/466
JVM

321/466

Nothing to mention?

322/466
APIS

323/466
JEP-400: UTF-8 by Default 
UTF-8 by default

Consistent behaviour
– Implementations
– Operating systems
– Locales

Except for console I/O
https://en.wikipedia.org/wiki/UTF-8
Declared character set for the 10 million
most popular websites, since 2010

324/466
JEP-408: Simple Web Server 
Command-line tool
–Different from JEP-321

Minimal Web server
–Static files only
–No CGI or servlets
https://www.baeldung.com/simple-web-server-java-18
jwebserver -d /opt
Binding to loopback by default.
For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /opt and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/

325/466
JEP-408: Simple Web Server
final
InetSocketAddress
address
=
new
InetSocketAddress(8080);
final
Path
path1
= Path.of(
"D:\\Documents\\Tutorials\\220926 - New Java"
);
final
HttpServer
server
= SimpleFileServer.createFileServer(
address
,
path1
,
SimpleFileServer.OutputLevel.
VERBOSE
);
final
Path
path2
= Path.of(
"D:\\Documents\\Tutorials\\220926 - New Java\\Workspace"
);
final
HttpHandler
handler1
= SimpleFileServer.createFileHandler(
path2
);
server
.createContext(
"/test1"
,
handler1
);
final
HttpHandler
allowedResponse
= HttpHandlers.of(200, Headers.of(
"Allow"
,
"GET"
),
"Welcome"
);
final
HttpHandler
deniedResponse
= HttpHandlers.of(401, Headers.of(
"Deny"
,
"GET"
),
"Denied"
);
final
Predicate<Request>
findAllowedPath
=
r
->
r
.getRequestURI().getPath().equals(
"/test2/allowed"
);
final
HttpHandler
handler2
= HttpHandlers.handleOrElse(
findAllowedPath
,
allowedResponse
,
deniedResponse
);
server
.createContext(
"/test2"
,
handler2
);
server
.start();
https://www.baeldung.com/simple-web-server-java-18

326/466
JEP-416: Reflection with
Method Handles

Since Java 1.0
– sun.reflect.DelegatingMethodAccessorImpl
– jdk.internal.reflect.DelegatingMethod
AccessorImpl

Inflating implementation
–First, native code
–Then, dynamically-generated byte code
• With some uses of
sun.misc.Unsafe
– Since Java 1.4
https://blogs.oracle.com/javamagazine/post/java-reflection-m ethod-handles

327/466
JEP-416: Reflection with
Method Handles

Method handles ≈ Reflection API
https://blogs.oracle.com/javamagazine/post/java-reflection-m ethod-handles
int
compare(
final
String
str1
,
final
String
str2
) {
return
42; }
int
compare(
final
String
str
,
final int
i
) {
return
24; }
public static void
main(
final
String[]
args
)
throws
Throwable {
var
lookup
= MethodHandles.lookup();
var
methodType1
= MethodType.methodType(
int
.
class
, String.
class
, String.
class
);
System.
out
.println(
"MethodType : "
+
methodType1
);
var
methodHandle1
=
lookup
.findVirtual(
lookup
.lookupClass(),
"compare"
,
methodType1
);
System.
out
.println(
"MethodHandle: "
+
methodHandle1
.type());
System.
out
.println(
methodHandle1
.invoke(
new
Example1(),
"Hello"
,
"World!"
));
var
methodType2
= MethodType.methodType(
int
.
class
, String.
class
,
int
.
class
);
var
methodHandle2
=
lookup
.findVirtual(
lookup
.lookupClass(),
"compare"
,
methodType2
);
System.
out
.println(
methodHandle2
.invoke(
new
Example1(),
"Hello"
, 0));
}

328/466
JEP-416: Reflection with
Method Handles

Method handles ≈ Reflection API
https://blogs.oracle.com/javamagazine/post/java-reflection-m ethod-handles
int
compare(
final
String
str1
,
final
String
str2
) {
return
42; }
int
compare(
final
String
str
,
final int
i
) {
return
24; }
public static void
main(
final
String[]
args
)
throws
Throwable {
var
lookup
= MethodHandles.lookup();
var
methodType1
= MethodType.methodType(
int
.
class
, String.
class
, String.
class
);
System.
out
.println(
"MethodType : "
+
methodType1
);
var
methodHandle1
=
lookup
.findVirtual(
lookup
.lookupClass(),
"compare"
,
methodType1
);
System.
out
.println(
"MethodHandle: "
+
methodHandle1
.type());
System.
out
.println(
methodHandle1
.invoke(
new
Example1(),
"Hello"
,
"World!"
));
var
methodType2
= MethodType.methodType(
int
.
class
, String.
class
,
int
.
class
);
var
methodHandle2
=
lookup
.findVirtual(
lookup
.lookupClass(),
"compare"
,
methodType2
);
System.
out
.println(
methodHandle2
.invoke(
new
Example1(),
"Hello"
, 0));
}
Introspection, really

329/466
JEP-416: Reflection with
Method Handles

MethodHandles.
lookup()
– Methods, fields
accessible where the
lookup object is created
– Inaccessible methods
are not visible from the
lookup context

MethodHandle.
invoke()
– Any arguments
– Any return type
– Varags (cf. Java 7)
https://blogs.oracle.com/javamagazine/post/java-reflection-m ethod-handles
public final native @
PolymorphicSignature
Object invoke(Object...)
throws
Throwable;

330/466
JEP-416: Reflection with
Method Handles

Method handles implement reflection
–Without changing the Reflection API!
• Since Java 1.1
–If old implementation is needed 
Less overhead
– MethodHandle.invokeWithArguments()
callable by reflection and JNI
https://blogs.oracle.com/javamagazine/post/java-reflection-m ethod-handles
Djdk.reflect.useDirectMethodHandle=false

331/466
JEP-418: Internet-address
Resolution SPI

Service-provider
interface (SPI) for
host name and
address resolution

Use (module) services
– Cf. JSR-376

java.net.InetAddress can use resolvers
– Others than the OS
built-in resolver
• hostsfile and Domain
Name System (DNS)
public sealed class
InetAddress
implements
Serializable
permits
Inet4Address, Inet6Address {
private static
InetAddressResolver loadResolver() {
return
ServiceLoader.load(InetAddressResolverProvider.
class
)
.findFirst()
.map(
nsp
->
nsp
.get(builtinConfiguration()))
.orElse(
BUILTIN_RESOLVER
);
}

332/466
JEP-418: Internet-address
Resolution SPI

Service-provider
interface (SPI) for
host name and
address resolution

Use (module) services
– Cf. JSR-376

java.net.InetAddress can use resolvers
– Others than the OS
built-in resolver
• hostsfile and Domain
Name System (DNS)
public sealed class
InetAddress
implements
Serializable
permits
Inet4Address, Inet6Address {
private static
InetAddressResolver loadResolver() {
return
ServiceLoader.load(InetAddressResolverProvider.
class
)
.findFirst()
.map(
nsp
->
nsp
.get(builtinConfiguration()))
.orElse(
BUILTIN_RESOLVER
);
}
sealed class with two subclasses
ServiceLoaderwith default object

333/466
MISC

334/466

Nothing to mention?

335/466
Java 19
2022/09/20

336/466

Only previews or incubator

337/466
Java 20
2023/03/21

338/466

Only previews or incubator

339/466
Java 21
2023/09/19

340/466
LANGUAGE

341/466
JEP-440: Record Patterns 
Since Java 16
– instanceof
pattern matching
–Records
–Cf. JEP-394, JEP-395

Record patterns for record values

342/466
JEP-440: Record Patterns
record
Person(String
firstName
, String
lastName
) {
}
public class
Example1 {
public static void
main(
final
String[]
args
) {
final
Person
person1
=
new
Person(
"Rick"
,
"Deckard"
);
final
Person
person2
=
new
Person(
"Roy"
,
"Batty"
);
final
Object
o1
=
person1
;
if
(
o1
instanceof
Person
p
) {
System.
out
.println(
p
.firstName());
}
final
Object
o2
=
person2
;
if
(
o2
instanceof final
Person(
final
String
first
,
final
String
last
)) {
System.
out
.println(
first
);
}
}
}

343/466
JEP-440: Record Patterns
record
Person(String
firstName
, String
lastName
) {
}
public class
Example1 {
public static void
main(
final
String[]
args
) {
final
Person
person1
=
new
Person(
"Rick"
,
"Deckard"
);
final
Person
person2
=
new
Person(
"Roy"
,
"Batty"
);
final
Object
o1
=
person1
;
if
(
o1
instanceof
Person
p
) {
System.
out
.println(
p
.firstName());
}
final
Object
o2
=
person2
;
if
(
o2
instanceof final
Person(
final
String
first
,
final
String
last
)) {
System.
out
.println(
first
);
}
}
}
Rick
Roy

344/466
JEP-441: switchPattern Matching
final
String
response
=
"Yes"
;
switch
(
response
) {
case null
-> {
System.
out
.println(
"Boom!"
);
}
case
String
s
when
s
.equalsIgnoreCase(
"YES"
) -> {
System.
out
.println(
"You got it"
);
}
case
String
s
when
s
.equalsIgnoreCase(
"NO"
) -> {
System.
out
.println(
"Too bad"
);
}
case
String
s
-> {
System.
out
.println(
"Sorry?"
);
}
}

345/466
JEP-441: switchPattern Matching
final
String
response
=
"Yes"
;
switch
(
response
) {
case null
-> {
System.
out
.println(
"Boom!"
);
}
case
String
s
when
s
.equalsIgnoreCase(
"YES"
) -> {
System.
out
.println(
"You got it"
);
}
case
String
s
when
s
.equalsIgnoreCase(
"NO"
) -> {
System.
out
.println(
"Too bad"
);
}
case
String
s
-> {
System.
out
.println(
"Sorry?"
);
}
}
You got it

346/466
JVM

347/466
JEP-439: Generational ZGC 
Since Java 15
–Z Garbage Collector (ZGC)
–Cf. JEP-377

Separate generations for young, old objects
–More frequent collection of young objects
–Minimal manual configuration
-XX:+UseZGC -XX:+ZGenerational

348/466
APIS

349/466
JEP-431: Sequenced Collections 
Inconsistencies in the collections
–First, last elements
–Reverse order
https://www.baeldung.com/java-21-sequenced-collections
Last Element First Elementlist.get(list.size() – 1) list.get(0) List
deque.getLast() deque.getFirst() Deque
sortedSet.last() sortedSet.first() SortedSet
Missing linkedHS.iterator().next() LinkedHashSet

350/466
JEP-431: Sequenced Collections
https://www.baeldung.com/java-21-sequenced-collections

351/466
JEP-431: Sequenced Collections
https://www.baeldung.com/java-21-sequenced-collections
public interface
SequencedCollection<E>
extends
Collection<E> {
SequencedCollection<E> reversed();
default void
addFirst(E
e
) {
throw new
UnsupportedOperationException();
}
default void
addLast(E
e
) {
throw new
UnsupportedOperationException();
}
default
E getFirst() {
return this
.iterator().next();
}
default
E getLast() {
return this
.reversed().iterator().next();
}
default
E removeFirst() {
var
it
=
this
.iterator();
E
e
=
it
.next();
it
.remove();
return
e
;
}
default
E removeLast() {
var
it
=
this
.reversed().iterator();
E
e
=
it
.next();
it
.remove();
return
e
;
}
}
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
.getFirst());
System.
out
.println(
list
.getLast());
}

352/466
JEP-431: Sequenced Collections
https://www.baeldung.com/java-21-sequenced-collections
public interface
SequencedCollection<E>
extends
Collection<E> {
SequencedCollection<E> reversed();
default void
addFirst(E
e
) {
throw new
UnsupportedOperationException();
}
default void
addLast(E
e
) {
throw new
UnsupportedOperationException();
}
default
E getFirst() {
return this
.iterator().next();
}
default
E getLast() {
return this
.reversed().iterator().next();
}
default
E removeFirst() {
var
it
=
this
.iterator();
E
e
=
it
.next();
it
.remove();
return
e
;
}
default
E removeLast() {
var
it
=
this
.reversed().iterator();
E
e
=
it
.next();
it
.remove();
return
e
;
}
}
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
.getFirst());
System.
out
.println(
list
.getLast());
}
Neat use of default
methods (cf. Java 8)

353/466
JEP-431: Sequenced Collections
https://www.baeldung.com/java-21-sequenced-collections
public interface
SequencedCollection<E>
extends
Collection<E> {
SequencedCollection<E> reversed();
default void
addFirst(E
e
) {
throw new
UnsupportedOperationException();
}
default void
addLast(E
e
) {
throw new
UnsupportedOperationException();
}
default
E getFirst() {
return this
.iterator().next();
}
default
E getLast() {
return this
.reversed().iterator().next();
}
default
E removeFirst() {
var
it
=
this
.iterator();
E
e
=
it
.next();
it
.remove();
return
e
;
}
default
E removeLast() {
var
it
=
this
.reversed().iterator();
E
e
=
it
.next();
it
.remove();
return
e
;
}
}
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
.getFirst());
System.
out
.println(
list
.getLast());
}
Rick Deckard
Mary
Neat use of default
methods (cf. Java 8)

354/466
JEP-444: Virtual Threads 
Since Java 1.0
–Thread-per-request style
–Limited number of available threads

High-throughput concurrent programs

Virtual threads
–Lightweight threads
–Ease writing, maintaining, and observing

355/466
JEP-444: Virtual Threads
https://davidvlijmincx.com/posts/create_virtual_threads_with_ project_loom/
final
Runnable
printThread
= () -> System.
out
.println(Thread.currentThread());
new
Thread(
printThread
).start();
final
ThreadFactory
threadFactory1
= Thread.ofPlatform().factory();
final
Thread
platformThread2
=
threadFactory1
.newThread(
printThread
);
platformThread2
.start();
Thread.startVirtualThread(
printThread
);
final
ThreadFactory
threadFactory2
= Thread.ofVirtual().factory();
final
Thread
virtualThread2
=
threadFactory2
.newThread(
printThread
);
virtualThread2
.start();

356/466
JEP-444: Virtual Threads
https://davidvlijmincx.com/posts/create_virtual_threads_with_ project_loom/
final
Runnable
printThread
= () -> System.
out
.println(Thread.currentThread());
new
Thread(
printThread
).start();
final
ThreadFactory
threadFactory1
= Thread.ofPlatform().factory();
final
Thread
platformThread2
=
threadFactory1
.newThread(
printThread
);
platformThread2
.start();
Thread.startVirtualThread(
printThread
);
final
ThreadFactory
threadFactory2
= Thread.ofVirtual().factory();
final
Thread
virtualThread2
=
threadFactory2
.newThread(
printThread
);
virtualThread2
.start();
Thread[#20,Thread-0,5,main]
Thread[#21,Thread-1,5,main]
VirtualThread[#22]/runnable@ForkJoinPool-1-worker-1
VirtualThread[#24]/runnable@ForkJoinPool-1-worker-2

357/466
JEP-452: Key Encapsulation
Mechanism API

Key encapsulation mechanisms (KEMs)
–Securing symmetric keys
–Using public key cryptography

Enable programs to use KEM algorithms

Allow implementations of KEM algorithms
–Java code
–Native code

358/466
MISC

359/466
JEP-445: Unnamed Classes and
Instance Main Methods

Reduce barrier to entry

Mimic scripting languages
public class
Example1 {
public static void
main(
final
String[]
args
) {
System.
out
.println(
"Hello, World!"
);
}
}

360/466
JEP-445: Unnamed Classes and
Instance Main Methods

Reduce barrier to entry

Mimic scripting languages
public class
Example1 {
public static void
main(
final
String[]
args
) {
System.
out
.println(
"Hello, World!"
);
}
}
void
main() {
System.out.println(
"Hello, World!"
);
}

361/466
JEP-445: Unnamed Classes and
Instance Main Methods
void
main() {
System.
out
.println(
"Hello, World!"
);
final
Class
clazz
=
this
.getClass();
System.
out
.println(
clazz
.getName());
System.
out
.println(
clazz
.getPackage().getName());
System.
out
.println(
clazz
.getModule().getName());
}
Example3.java

362/466
JEP-445: Unnamed Classes and
Instance Main Methods
java --source 22 --enable-preview Example3.java
void
main() {
System.
out
.println(
"Hello, World!"
);
final
Class
clazz
=
this
.getClass();
System.
out
.println(
clazz
.getName());
System.
out
.println(
clazz
.getPackage().getName());
System.
out
.println(
clazz
.getModule().getName());
}
Example3.java

363/466
JEP-445: Unnamed Classes and
Instance Main Methods
java --source 22 --enable-preview Example3.java
void
main() {
System.
out
.println(
"Hello, World!"
);
final
Class
clazz
=
this
.getClass();
System.
out
.println(
clazz
.getName());
System.
out
.println(
clazz
.getPackage().getName());
System.
out
.println(
clazz
.getModule().getName());
}
Hello, World!
Example3
null
Example3.java

364/466
JEP-445: Unnamed Classes and
Instance Main Methods
java --source 22 --enable-preview Example3.java
void
main() {
System.
out
.println(
"Hello, World!"
);
final
Class
clazz
=
this
.getClass();
System.
out
.println(
clazz
.getName());
System.
out
.println(
clazz
.getPackage().getName());
System.
out
.println(
clazz
.getModule().getName());
}
Hello, World!
Example3
null
Example3.java
Why empty?
Why null?

365/466
JEP-445: Unnamed Classes and
Instance Main Methods
java --source 22 --enable-preview Example3.java
void
main() {
System.
out
.println(
"Hello, World!"
);
final
Class
clazz
=
this
.getClass();
System.
out
.println(
clazz
.getName());
System.
out
.println(
clazz
.getPackage().getName());
System.
out
.println(
clazz
.getModule().getName());
}
Hello, World!
Example3
null
Example3.java
Why empty?
Why null?
Using javac22 to compile

366/466
JEP-445: Unnamed Classes and
Instance Main Methods

Without main()
// Compiled from Example3.java (version 22 : 66.65535, super bit)
final class Example3 {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
Example3();
0 aload_0 [this]
1 invokespecial java.lang.Object()
4 return
Line numbers:
[pc: 0, line: 7]
// Method descriptor #6 ()V
// Stack: 2, Locals: 2
void main();
0 getstatic java.lang.System.out : java.io.PrintStream
3 ldc <String "Hello, World!">
5 invokevirtual java.io.PrintStream.println(java.lang.String) : void
[...]
49 return
[...]
}
Example3.java:7: error: implicitly declared class d oes not have
main method in the form of void main() or void main (String[] args)

367/466
JEP-445: Unnamed Classes and
Instance Main Methods

Without main()
// Compiled from Example3.java (version 22 : 66.65535, super bit)
final class Example3 {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
Example3();
0 aload_0 [this]
1 invokespecial java.lang.Object()
4 return
Line numbers:
[pc: 0, line: 7]
// Method descriptor #6 ()V
// Stack: 2, Locals: 2
void main();
0 getstatic java.lang.System.out : java.io.PrintStream
3 ldc <String "Hello, World!">
5 invokevirtual java.io.PrintStream.println(java.lang.String) : void
[...]
49 return
[...]
}
Example3.java:7: error: implicitly declared class d oes not have
main method in the form of void main() or void main (String[] args)
Autogenerated

368/466
JEP-445: Unnamed Classes and
Instance Main Methods

Without main()
// Compiled from Example3.java (version 22 : 66.65535, super bit)
final class Example3 {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
Example3();
0 aload_0 [this]
1 invokespecial java.lang.Object()
4 return
Line numbers:
[pc: 0, line: 7]
// Method descriptor #6 ()V
// Stack: 2, Locals: 2
void main();
0 getstatic java.lang.System.out : java.io.PrintStream
3 ldc <String "Hello, World!">
5 invokevirtual java.io.PrintStream.println(java.lang.String) : void
[...]
49 return
[...]
}
Example3.java:7: error: implicitly declared class d oes not have
main method in the form of void main() or void main (String[] args)
Autogenerated
Known by the JVM

369/466
Java 22
2024/03/19

370/466
LANGUAGE

371/466
JEP-456: Unnamed Variables and
Patterns

Prevent unwarranted warnings
final
List<Order>
orders
=
new
ArrayList<>();
int
total
= 0;
for
(
final
Order
o
:
orders
) {
total
++;
}
System.
out
.println(
total
);

372/466
JEP-456: Unnamed Variables and
Patterns

Prevent unwarranted warnings
final
List<Order>
orders
=
new
ArrayList<>();
int
total
= 0;
for
(
final
Order
o
:
orders
) {
total
++;
}
System.
out
.println(
total
);
Warning: The value of the
local variable ois not used

373/466
JEP-456: Unnamed Variables and
Patterns

Prevent unwarranted warnings
final
List<Order>
orders
=
new
ArrayList<>();
int
total
= 0;
for
(
final
Order
o
:
orders
) {
total
++;
}
System.
out
.println(
total
);
final
List<Order>
orders
=
new
ArrayList<>();
int
total
= 0;
for
(
final
Order
_
:
orders
) {
total
++;
}
System.
out
.println(
total
);
Warning: The value of the
local variable ois not used

374/466
JEP-456: Unnamed Variables and
Patterns

Prevent unwarranted warnings
final
List<Order>
orders
=
new
ArrayList<>();
int
total
= 0;
for
(
final
Order
o
:
orders
) {
total
++;
}
System.
out
.println(
total
);
final
List<Order>
orders
=
new
ArrayList<>();
int
total
= 0;
for
(
final
Order
_
:
orders
) {
total
++;
}
System.
out
.println(
total
);
Warning: The value of the
local variable ois not used
Unnamed variable

375/466
JVM

376/466
JEP-423: Region Pinning for G1 
Since Java 9
– G1

Since Java 10
– JEP-307

Since Java 12
– JEP-344
– JEP-346 
Since Java 14
– JEP-345

Reduce latency with
region pinning
– GC continues even if a
critical region was created
by some JNI code
• GetPrimitiveArrayCritical,
GetStringCritical
• References to arrays or
Strings in the heap
• References held until
release functions called

377/466
JEP-454: Foreign Function and
Memory API

Foreign Function and
Memory (FFM) API
–Productivity: replace brittle JNI
with a concise, readable, and
pure-Java API
–Performance: access to FFM
with overhead comparable to
JNI (and Unsafe)
–Support: discovery and
invocation of native libraries
on every OS with the JVM
–Uniformity: operations for
structured/unstructured data
(no matter size, kind)
–Soundness: no use-after-free
bugs, even with (de)allocations
by multiple threads
–Integrity: warning for unsafe
operations with native code
and data
https://www.infoq.com/news/2023/10/foreign-function-and -memory-api/

378/466
JEP-454: Foreign Function and
Memory API
https://www.infoq.com/news/2023/10/foreign-function-and -memory-api/
private
String[] sort(
final
String[]
strings
) {
final
Linker
linker
= Linker.nativeLinker();
final
SymbolLookup
stdlib
=
linker
.defaultLookup();
final
MemorySegment
radixSort
=
stdlib
.find(
"radixsort"
).orElseThrow();
final
MethodHandle
methodHandle
=
linker
.downcallHandle(
radixSort
,
FunctionDescriptor.ofVoid(ValueLayout.
ADDRESS
, ValueLayout.
JAVA_INT
,
ValueLayout.
ADDRESS
, ValueLayout.
JAVA_CHAR
));
try
(
final
Arena
arena
= Arena.ofConfined()) {
final
MemorySegment
pointers
=
arena
.allocateArray(ValueLayout.
ADDRESS
,
strings
.
length
);
for
(
int
i
= 0;
i
<
strings
.
length
;
i
++) {
final
MemorySegment
cString
=
arena
.allocateUtf8String(
strings
[
i
]);
pointers
.setAtIndex(ValueLayout.
ADDRESS
,
i
,
cString
);
}
methodHandle
.invoke(
pointers
,
strings
.
length
, MemorySegment.
NULL
,
'\0’
);
for
(
int
i
= 0;
i
<
strings
.
length
;
i
++) {
MemorySegment
cString
=
pointers
.getAtIndex(ValueLayout.
ADDRESS
,
i
);
cString
=
cString
.reinterpret(Long.
MAX_VALUE
);
strings
[
i
] =
cString
.getUtf8String(0);
}
}
catch
(
final
Throwable
e
) {
throw new
RuntimeException(
e
);
}
return
strings
;
}

379/466
APIS

380/466

Nothing to mention?

381/466
MISC

382/466
JEP-458: Multi-file Source -code
Programs Launching

Lower the (early) learning curve
–But no dependency management
java –cp * Prog1.java
Prog1.java
Prog2.java
Helper.java
library1.jar
library2.jar

383/466
Java 23
2024/09/18

384/466
Disclaimer 
Lots of preview/incubating features…
Some still worth mentioning!
(With titles in italic)

385/466
LANGUAGE

386/466
JEP-445: Primitive Types in
Patterns, instanceof, and switch

Systematic and consistent (everywhere?)
uses of pattern-matching
final int
someIntValue
= 42;
switch
(
someIntValue
) {
case
0 -> System.
out
.println(
"Got 0"
);
case
1 -> System.
out
.println(
"Got 1"
);
case
2 -> System.
out
.println(
"Got 2"
);
case int
i
when
i
>= 100 -> System.
out
.println(
"Got "
+
i
+
" >= 100"
);
case int
i
-> System.
out
.println(
"Got "
+
i
+
" >2 and <100"
);
}

387/466
JEP-445: Primitive Types in
Patterns, instanceof, and switch

Requires conversion, questions safety
boolean double float long int Char short byte To →
From ↓
— ɛ ɛ ɛ ɛ ωη ɛ ≈ byte
— ɛ ɛ ɛ ɛ η ≈ η short
— ɛ ɛ ɛ ɛ ≈ η η char
— ɛ ω ɛ ≈ η η η int
— ω ω ≈ η η η η long
— ɛ ≈ η η η η η float
— ≈ η η η η η η double
≈ — — — — — — — boolean

388/466
JEP-482: Flexible
Constructor Bodies

“Fail Fast”
class
ValidationWithAuxiliaryMethod
extends
BigDecimal {
private static long
checkPositive(
final long
value
) {
if
(
value
<= 0)
throw new
IllegalArgumentException(
"..."
);
return
value
;
}
public
ValidationWithAuxiliaryMethod(
final long
value
) {
super
(checkPositive(
value
));
}
}

389/466
JEP-482: Flexible
Constructor Bodies

“Fail Fast”
class
ValidationWithAuxiliaryMethod
extends
BigDecimal {
private static long
checkPositive(
final long
value
) {
if
(
value
<= 0)
throw new
IllegalArgumentException(
"..."
);
return
value
;
}
public
ValidationWithAuxiliaryMethod(
final long
value
) {
super
(checkPositive(
value
));
}
}
class
ValidationInConstructor
extends
BigInteger {
public
ValidationInConstructor(
final long
value
) {
if
(
value
<= 0)
throw new
IllegalArgumentException(
"..."
);
super
(
value
);
...

390/466
JVM

391/466
JEP-474: ZGC: Generational Mode
by Default

What can I say?

392/466
APIS

393/466
JEP-466: Class-File API 
Manipulate class-files directly in Java
ClassFile.of().buildTo(Path.of(
"A.class"
), ClassDesc.of(
"A"
),
classBuilder
->
classBuilder
.withMethod(
"fooBar"
,
MethodTypeDesc.of(
CD_void
,
CD_boolean
,
CD_int
),
AccessFlags.ofMethod(AccessFlag.
PUBLIC
).flagsMask(),
methodBuilder
->
methodBuilder
.withCode(
codeBuilder
-> {
final
Label
label1
=
codeBuilder
.newLabel();
final
Label
label2
=
codeBuilder
.newLabel();
codeBuilder
.iload(1).ifeq(
label1
).aload(0).iload(2)
.invokevirtual(ClassDesc.of(
"Foo"
),
"foo"
,
MethodTypeDesc.of(
CD_void
,
CD_int
))
.goto_(
label2
).labelBinding(
label1
).aload(0)
.iload(2)
.invokevirtual(ClassDesc.of(
"Foo"
),
"bar"
,
MethodTypeDesc.of(
CD_void
,
CD_int
))
.labelBinding(
label2
).return_();
})));

394/466
JEP-469: Vector API 
“Introduce an API to express vector
computations that reliably compile at runtime
to optimal vector instructions on supported
CPU architectures, thus achieving
performance superior to equivalent scalar
computations.”

395/466
JEP-469: Vector API static final
VectorSpecies<Float>
SPECIES
=
FloatVector.SPECIES_PREFERRED;
void
vectorComputation(
float
[]
a
,
float
[]
b
,
float
[]
c
) {
int
i
= 0;
int
upperBound
=
SPECIES
.loopBound(
a
.
length
);
for
(;
i
<
upperBound
;
i
+=
SPECIES
.length()) {
// FloatVector va, vb, vc; var
va
= FloatVector.fromArray(
SPECIES
,
a
,
i
);
var
vb
= FloatVector.fromArray(
SPECIES
,
b
,
i
);
var
vc
=
va
.mul(
va
).add(
vb
.mul(
vb
)).neg();
vc
.intoArray(
c
,
i
);
}
for
(;
i
<
a
.
length
;
i
++) {
c
[
i
] = (
a
[
i
] *
a
[
i
] +
b
[
i
] *
b
[
i
]) * -1.0f;
}
}

396/466
JEP-476: Module Import
Declarations

Simplify the use of modules
import module
M1;
public class
Example1 {
...
module
M1 {
exports
p1;
exports
p2
to
M0;
exports
p3
to
M3;
requires transitive
M4;
requires
M5;
}
module
M3 { ... }
module
M4 {
exports
p10;
}
module
M5 {
exports
p11;
}

397/466
JEP-476: Module Import
Declarations

Simplify the use of modules
import module
M1;
public class
Example1 {
...
module
M1 {
exports
p1;
exports
p2
to
M0;
exports
p3
to
M3;
requires transitive
M4;
requires
M5;
}
module
M3 { ... }
module
M4 {
exports
p10;
}
module
M5 {
exports
p11;
}

398/466
JEP-476: Module Import
Declarations

Simplify the use of modules
import module
M1;
public class
Example1 {
...
module
M1 {
exports
p1;
exports
p2
to
M0;
exports
p3
to
M3;
requires transitive
M4;
requires
M5;
}
module
M3 { ... }
module
M4 {
exports
p10;
}
module
M5 {
exports
p11;
}

399/466
JEP-476: Module Import
Declarations

Simplify the use of modules
import module
M1;
public class
Example1 {
...
module
M1 {
exports
p1;
exports
p2
to
M0;
exports
p3
to
M3;
requires transitive
M4;
requires
M5;
}
module
M3 { ... }
module
M4 {
exports
p10;
}
module
M5 {
exports
p11;
}

400/466
JEP-481: Scoped Values 
Client-dependent context

Alternative to ThreadLocal
class
Framework {
private final static
ScopedValue<FrameworkContext>
CONTEXT
=
ScopedValue.newInstance();
void
serve(Request
request
, Response
response
) {
var
context
= createContext(
request
);
ScopedValue.runWhere(
CONTEXT
,
context
,
() -> Application.handle(
request
,
response
));
}
public
PersistedObject readKey(String
key
) {
var
context
=
CONTEXT
.get();
var
db
= getDBConnection(
context
);
db
.readKey(
key
);
...

401/466
MISC

402/466
JEP-471: Deprecate the Memory-
Access Methods for Removal
class
OffHeapArray {
private final static int
BYTE_SIZE
= 1;
private long
size
;
private long
address
;
public
OffHeapArray(
final long
size
)
throws
... {
this
.
size
=
size
;
this
.
address
=
this
.getUnsafe().allocateMemory(
this
.
size
*
BYTE_SIZE
);
}
private
Unsafe getUnsafe()
throws
... {
final
Field
f
= Unsafe.
class
.getDeclaredField(
"theUnsafe"
);
f
.setAccessible(
true
);
return
(Unsafe)
f
.get(
null
);
}
public void
set(
final long
idx
,
final byte
value
)
throws
... {
this
.getUnsafe().putByte(
this
.
address
+
idx
*
BYTE_SIZE
,
value
);
}
public int
get(
final long
idx
)
throws
... {
return this
.getUnsafe().getByte(
this
.
address
+
idx
*
BYTE_SIZE
);
}
public void
freeMemory()
throws
... {
this
.getUnsafe().freeMemory(
this
.
address
);
}
...

403/466
JEP-471: Deprecate the Memory-
Access Methods for Removal
final
OffHeapArray
oha
=
new
OffHeapArray(3);
oha
.set(0, (
byte
) 42);
oha
.set(1, (
byte
) 84);
oha
.set(2, (
byte
) 111);
System.
out
.println(
oha
.get(0));
System.
out
.println(
oha
.get(1));
System.
out
.println(
oha
.get(2));
oha
.freeMemory();

404/466
JEP-471: Deprecate the Memory-
Access Methods for Removal
final
OffHeapArray
oha
=
new
OffHeapArray(3);
oha
.set(0, (
byte
) 42);
oha
.set(1, (
byte
) 84);
oha
.set(2, (
byte
) 111);
System.
out
.println(
oha
.get(0));
System.
out
.println(
oha
.get(1));
System.
out
.println(
oha
.get(2));
oha
.freeMemory();
final
OffHeapArray
oha
=
new
OffHeapArray(1);
oha
.set(0, (
byte
) 42);
oha
.set(1, (
byte
) 84);
oha
.set(2, (
byte
) 111);
System.
out
.println(
oha
.get(0));
System.
out
.println(
oha
.get(1));
System.
out
.println(
oha
.get(2));
oha
.freeMemory();
Where am I writing?

405/466
JEP-477: Implicitly Declared Classes
and Instance Main Methods

Java Python-isation
continues…
– “thereby avoiding the
mysterious
System.out.println”
public class
HelloWorld {
public static void
main(String[]
args
) {
System.
out
.println(
"Hello, World!"
);
}
}

406/466
JEP-477: Implicitly Declared Classes
and Instance Main Methods

Java Python-isation
continues…
– “thereby avoiding the
mysterious
System.out.println”
public class
HelloWorld {
public static void
main(String[]
args
) {
System.
out
.println(
"Hello, World!"
);
}
}
class
HelloWorld {
void
main() {
System.out.println(
"Hello, World!"
);
}
}

407/466
JEP-477: Implicitly Declared Classes
and Instance Main Methods

Java Python-isation
continues…
– “thereby avoiding the
mysterious
System.out.println”
public class
HelloWorld {
public static void
main(String[]
args
) {
System.
out
.println(
"Hello, World!"
);
}
}
class
HelloWorld {
void
main() {
System.out.println(
"Hello, World!"
);
}
}
void
main() {
System.out.println(
"Hello, World!"
);
}

408/466
JEP-477: Implicitly Declared Classes
and Instance Main Methods

Java Python-isation
continues…
– “thereby avoiding the
mysterious
System.out.println”
public class
HelloWorld {
public static void
main(String[]
args
) {
System.
out
.println(
"Hello, World!"
);
}
}
class
HelloWorld {
void
main() {
System.out.println(
"Hello, World!"
);
}
}
void
main() {
println(
"Hello, World!"
);
}
void
main() {
System.out.println(
"Hello, World!"
);
}

409/466
Java 24 2025/03/18

410/466
LANGUAGE

411/466
Language 
Some preview features…
Some still worth mentioning!

412/466
Language 
JEP-487: Scoped Values
– Fourth Preview

JEP-488: Primitive Types in Patterns, instanceof
, and
switch
– Second Preview

JEP-492: Flexible Constructor Bodies
– Third Preview

JEP-494: Module Import Declarations
– Second Preview

413/466
JVM

414/466
JEP-475: Late Barrier Expansion for G1 
Reduces overall JVM overhead
–For optimising JIT compilers, e.g., JDK’s C2

Expanding G1 barriers early increases C2
overhead by 10-20%

415/466
JEP-475: Late Barrier Expansion for G1

416/466
JEP-475: Late Barrier Expansion for G1

417/466
JEP-490: ZGC: Remove the Non-
Generational Mode

Remove the non-generational mode

418/466
JEP-490: ZGC: Remove the Non-
Generational Mode

Remove the non-generational mode

What can I say?

419/466
JEP-483: Ahead-of-Time Class
Loading and Linking

Most applications start up follow the same
steps every time they run

Extend the HotSpot JVM to support an
ahead-of-time cache
–Evolution of class-data sharing

420/466
JEP-483: Ahead-of-Time Class
Loading and Linking

Requires three steps
–Training run
–Cache creation
–Cache utilisation
$ java -cp bin/ net.ptidej.newjava.aotcache.Main
Some application doing lots of things at start up...
$ java
----XX:AOTMode=record XX:AOTMode=record XX:AOTMode=record XX:AOTMode=record ----XX:AOTConfiguration=app.aotconf XX:AOTConfiguration=app.aotconf XX:AOTConfiguration=app.aotconf XX:AOTConfiguration=app.aotconf
\
-cp bin/ net.ptidej.newjava.aotcache.Main
Some application doing lots of things at start up...
$ java
----XX:AOTMode=create XX:AOTMode=create XX:AOTMode=create XX:AOTMode=create ----XX:AOTConfiguration=app.aotconf XX:AOTConfiguration=app.aotconf XX:AOTConfiguration=app.aotconf XX:AOTConfiguration=app.aotconf ----XX:AOTCache=app.aot XX:AOTCache=app.aot XX:AOTCache=app.aot XX:AOTCache=app.aot
\
-cp bin/ net.ptidej.newjava.aotcache.Main
[0.237s][warning][cds] Skipping net/.../Main: Unsupported location
AOTCache creation is complete: app.aot
$ java
----XX:AOTCache=app.aot XX:AOTCache=app.aot XX:AOTCache=app.aot XX:AOTCache=app.aot
-cp bin/ net.ptidej.newjava.aotcache.Main
Some application doing lots of things at start up...

421/466
JEP-483: Ahead-of-Time Class
Loading and Linking

Creates two new files
–An AOT file
• Very large, binary file
• Classes are available instantlyfrom it
–An AOT configuration file
• Text file
$ java -cp bin/ net.ptidej.newjava.aotcache.Main
Some application doing lots of things at start up...
$ ll
total 4.1M
-r--r--r-- 1 yann None
9.0M 9.0M9.0M 9.0M
Mar 19 22:10 app.aot
-rw-r--r-- 1 yann None
42K42K42K 42K
Mar 19 22:09 app.aotconf
drwxr-xr-x 1 yann None 0 Mar 19 22:08 bin/
drwxr-xr-x 1 yann None 0 Mar 19 22:08 src/

422/466
JEP-483: Ahead-of-Time Class
Loading and Linking

Example of Spring PetClinic (!)
–Version 3.2.0
–Loads and links ~21,000 classes
–Startup times
• Without AOT cache 4.486s (JDK 23)
• With AOT cache 2.604s (JDK 24, 42%)

423/466
JEP-491: Synchronize Virtual
Threads without Pinning

Virtual threads

Platform threads

Arrange “for virtual threads that block in
[synchronizedmethods and blocks] to
release their underlying platform threads”

424/466
APIS

425/466
JEP-484: Class-File API 
Non-goals
–“[O]bsolete existing libraries [for] class files”
• Apache BCEL
• IBM CFParse
–“[E]xtend the Core Reflection API to give access
to the bytecode of loaded classes.”
• Would require changes to the JVM –“[P]rovide code analysis functionality”
• Should be provided by third-party libraries

426/466
JEP-484: Class-File API 
Manipulate class-files directly in Java
ClassFile.of().buildTo(Path.of(
"A.class"
), ClassDesc.of(
"A"
),
classBuilder
->
classBuilder
.withMethod(
"fooBar"
,
MethodTypeDesc.of(
CD_void
,
CD_boolean
,
CD_int
),
AccessFlags.ofMethod(AccessFlag.
PUBLIC
).flagsMask(),
methodBuilder
->
methodBuilder
.withCode(
codeBuilder
-> {
final
Label
label1
=
codeBuilder
.newLabel();
final
Label
label2
=
codeBuilder
.newLabel();
codeBuilder
.iload(1).ifeq(
label1
).aload(0).iload(2)
.invokevirtual(ClassDesc.of(
"Foo"
),
"foo"
,
MethodTypeDesc.of(
CD_void
,
CD_int
))
.goto_(
label2
).labelBinding(
label1
).aload(0)
.iload(2)
.invokevirtual(ClassDesc.of(
"Foo"
),
"bar"
,
MethodTypeDesc.of(
CD_void
,
CD_int
))
.labelBinding(
label2
).return_();
})));

427/466
JEP-485: Stream Gatherers 
Map-Reduce
– Processing, generating
large data sets
– Parallel and distributed

Streaming platforms
– Unified, high-throughput,
low-latency
– Apache Kafka

Sequence of data
– Declarative, functional
– Parallel and distributed
https://www.oracle.com/technical-resources/articles/java/ma14 -java-se-8-streams.html

428/466
JEP-485: Stream Gatherers
https://www.oracle.com/technical-resources/articles/java/ma14 -java-se-8-streams.html

429/466
JEP-485: Stream Gatherers private static final record
Transaction(Type
type
,
int
id
,
int
value
) {
enum
Type {
GROCERY
,
ENTERTAINMENT
; }
public
Type getType() {
return this
.
type
; }
public int
getValue() {
return this
.
value
; }
public int
getId() {
return this
.
id
; }
}
public static void
main(
final
String[]
args
) {
final
List<Transaction>
transactions
= List.of(
new
Transaction(Transaction.Type.
ENTERTAINMENT
, 1, 100),
new
Transaction(Transaction.Type.
GROCERY
, 3, 80),
new
Transaction(Transaction.Type.
GROCERY
, 6, 120),
new
Transaction(Transaction.Type.
ENTERTAINMENT
, 7, 40),
new
Transaction(Transaction.Type.
GROCERY
, 10, 50));
final
List<Integer>
transactionsIds
=
transactions
.parallelStream()
.filter(
t
->
t
.getType() == Transaction.Type.
GROCERY
)
.sorted(Comparator.comparing(Transaction::getValue).reversed())
.map(Transaction::getId).collect(Collectors.toList());
System.
out
.println(
transactionsIds
);
}

430/466
JEP-485: Stream Gatherers private static final record
Transaction(Type
type
,
int
id
,
int
value
) {
enum
Type {
GROCERY
,
ENTERTAINMENT
; }
public
Type getType() {
return this
.
type
; }
public int
getValue() {
return this
.
value
; }
public int
getId() {
return this
.
id
; }
}
public static void
main(
final
String[]
args
) {
final
List<Transaction>
transactions
= List.of(
new
Transaction(Transaction.Type.
ENTERTAINMENT
, 1, 100),
new
Transaction(Transaction.Type.
GROCERY
, 3, 80),
new
Transaction(Transaction.Type.
GROCERY
, 6, 120),
new
Transaction(Transaction.Type.
ENTERTAINMENT
, 7, 40),
new
Transaction(Transaction.Type.
GROCERY
, 10, 50));
final
List<Integer>
transactionsIds
=
transactions
.parallelStream()
.filter(
t
->
t
.getType() == Transaction.Type.
GROCERY
)
.sorted(Comparator.comparing(Transaction::getValue).reversed())
.map(Transaction::getId).collect(Collectors.toList());
System.
out
.println(
transactionsIds
);
}
[6, 3, 10]

431/466
JEP-485: Stream Gatherers 
Stateless vs. Stateful methods
– filter()
and
map()
– distinct()
and
sorted()
• limit()cuts short the processing
https://www.logicbig.com/tutorials/core-java-tutorial/ja va-util-stream/stream-cheat-sheet.html

432/466
JEP-485: Stream Gatherers 
In particular
– distinct()
uses
equals()
–E.g.,
String
content

@Override public void
accept(T
t
) {
if
(
t
==
null
) {
if
(!
seenNull
) {
seenNull
=
true
;
downstream
.accept(
lastSeen
=
null
);
}
}
else if
(
lastSeen
==
null
|| !
t
.equals(
lastSeen
)) {
downstream
.accept(
lastSeen
=
t
);
}
}

433/466
JEP-485: Stream Gatherers 
In particular
– distinct()
uses
equals()
–E.g.,
String
content

@Override public void
accept(T
t
) {
if
(
t
==
null
) {
if
(!
seenNull
) {
seenNull
=
true
;
downstream
.accept(
lastSeen
=
null
);
}
}
else if
(
lastSeen
==
null
|| !
t
.equals(
lastSeen
)) {
downstream
.accept(
lastSeen
=
t
);
}
}
Object::equals()

434/466
JEP-485: Stream Gatherers 
In particular
– distinct()
uses
equals()
–E.g.,
String
content

What if we want Stringlength?
@Override public void
accept(T
t
) {
if
(
t
==
null
) {
if
(!
seenNull
) {
seenNull
=
true
;
downstream
.accept(
lastSeen
=
null
);
}
}
else if
(
lastSeen
==
null
|| !
t
.equals(
lastSeen
)) {
downstream
.accept(
lastSeen
=
t
);
}
}
Object::equals()

435/466
JEP-485: Stream Gatherers 
Before, only equals()

Now, any method and stateful object
final
List<String>
result
= Stream
.of(
"foo"
,
"bar"
,
"bar"
,
"bar"
,
"zorg"
)
.distinct()
.toList();
final
DifferentLength
differentLength
=
new
DifferentLength();
final
List<String>
result
= Stream
.of(
"foo"
,
"bar"
,
"bar"
,
"bar"
,
"zorg"
)
.gather(Gatherer.ofSequential(
Integrator.ofGreedy(
differentLength
)))
.toList();

436/466
JEP-485: Stream Gatherers 
Or all-in-one
final
List<String>
result
= Stream
.of(
"foo"
,
"bar"
,
"bar"
,
"bar"
,
"zorg"
)
.gather(Gatherer.ofSequential(
DifferentLength::
new
,
Integrator.ofGreedy(DifferentLength::integrate),
DifferentLength::finish))
.toList();

437/466
JEP-485: Stream Gatherers class
DifferentLength {
private final
Set<Integer>
setOfLengths
;
DifferentLength() {
this
.
setOfLengths
=
new
HashSet<>(); }
boolean
integrate(
final
String
element
,
final
Downstream<?
super
String>
downstream
) {
final int
length
=
element
.length();
if
(!
setOfLengths
.contains(
length
)) {
setOfLengths
.add(
length
);
return
downstream
.push(
element
);
}
return true
;
}
void
finish(
final
Downstream<?
super
String>
downstream
) { }
}
final
List<String>
result
= Stream
.of(
"foo"
,
"bar"
,
"bar"
,
"bar"
,
"zorg"
)
.gather(Gatherer.<String, DifferentLength, String>ofSequential(
DifferentLength::
new
,
Integrator.<DifferentLength, String, String>ofGreedy(DifferentLength::integrate),
DifferentLength::finish))
.toList();

438/466
JEP-485: Stream Gatherers class
DifferentLength {
private final
Set<Integer>
setOfLengths
;
DifferentLength() {
this
.
setOfLengths
=
new
HashSet<>(); }
boolean
integrate(
final
String
element
,
final
Downstream<?
super
String>
downstream
) {
final int
length
=
element
.length();
if
(!
setOfLengths
.contains(
length
)) {
setOfLengths
.add(
length
);
return
downstream
.push(
element
);
}
return true
;
}
void
finish(
final
Downstream<?
super
String>
downstream
) { }
}
final
List<String>
result
= Stream
.of(
"foo"
,
"bar"
,
"bar"
,
"bar"
,
"zorg"
)
.gather(Gatherer.<String, DifferentLength, String>ofSequential(
DifferentLength::
new
,
Integrator.<DifferentLength, String, String>ofGreedy(DifferentLength::integrate),
DifferentLength::finish))
.toList();
Any desired state!

439/466
JEP-485: Stream Gatherers class
DifferentLength {
private

final
Set<Integer>
setOfLengths
;
DifferentLength() {
this
.
setOfLengths
=
new
HashSet<>(); }
boolean
integrate(

final
String
element
,
final
Downstream<?
super
String>
downstream
) {
final

int

length
=
element
.length();
if
(!
setOfLengths
.contains(
length
)) {
setOfLengths
.add(
length
);
return

downstream
.push(
element
);
}
return

true
;
}
void
finish(
final
Downstream<?
super
String>
downstream
) { }
}
final
List<String>
result
= Stream
.of(
"foo"
,
"bar"
,
"bar"
,
"bar"
,
"zorg"
)
.gather(Gatherer.<String, DifferentLength, String>ofSequential(
DifferentLength::
new
,
Integrator.<DifferentLength, String, String>ofGreedy(DifferentLength::integrate),
DifferentLength::finish))
.toList();
Any desired state! Not very clear…

440/466
JEP-485: Stream Gatherers 
The optional initialiserfunction provides an
object that maintains private state

The integratorfunction integrates a new
element from the input stream

The optional combinerfunction can evaluate
the gatherer in parallel for parallel streams

The optional finisher function is called when
there are no more input elements

441/466
JEP-496: Quantum-Resistant
Module-Lattice-Based Key
Encapsulation Mechanism
JEP-497: Quantum-Resistant
Module-Lattice-Based Digital
Signature Algorithm

Post-quantum cryptography
–Algorithms secured against a cryptanalytic
attack by a quantum computer

442/466
JEP-496 and JEP-497
https://www.wsj.com/articles/d-wave-claims-quantum-supremacy-beating-traditional-computers-155ca634

443/466
JEP-496 and JEP-497 
Six main approaches
1. Lattice-based cryptography
2. Multivariate cryptography
3. Hash-based cryptography
4. Code-based cryptography
5. Isogeny-based cryptography
6. Symmetric key quantum resistance

444/466
JEP-496 and JEP-497 
Six main approaches
1. Lattice-based cryptography 2. Multivariate cryptography
3. Hash-based cryptography
4. Code-based cryptography
5. Isogeny-based cryptography
6. Symmetric key quantum resistance

445/466
JEP-496 and JEP-497
final
KeyPairGenerator
kpgKEM
= KeyPairGenerator.getInstance(
"ML-KEM"
);
kpgKEM
.initialize(NamedParameterSpec.
ML_KEM_512
);
final
KeyPair
kpKEM
=
kpgKEM
.generateKeyPair();
// an ML-KEM-512 key pair
System.
out
.println(
kpKEM
.getPrivate());
System.
out
.println(
kpKEM
.getPublic());
final
KeyPairGenerator
kpgDSA
= KeyPairGenerator.getInstance(
"ML-DSA"
);
kpgDSA
.initialize(NamedParameterSpec.
ML_DSA_44
);
final
KeyPair
kpDSA
=
kpgDSA
.generateKeyPair();
// an ML-DSA-44 key pair
System.
out
.println(
kpDSA
.getPrivate());
System.
out
.println(
kpDSA
.getPublic());

446/466
JEP-498: Warn upon Use of Memory-
Access Methods in sun.misc.Unsafe

Now in module jdk.unsupported

79 out of 87 methods for accessing memory
–JVM’s garbage-collected heap
–Off-heap memory (out of the JVM’s control)

447/466
JEP-498: Warn upon Use of Memory-
Access Methods in sun.misc.Unsafe

java.lang.invoke.VarHandle
–JDK 9 (JEP-193)
–Safely and efficiently access on-heap memory,
i.e., fields of objects, fields of classes…

java.lang.foreign.MemorySegment
–JDK 22 (JEP-454)
–Safely and efficiently access off-heap memory,
c.f., Project Panama

448/466
JEP-498: Warn upon Use of Memory-
Access Methods in sun.misc.Unsafe

JDK 24: Warning

JDK 26+: Exception

JDK 27+: Removal of methods that have
standard and safe alternatives
WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::setMemory has been called by com.foo.bar.Server
(file:/tmp/foobarserver/thing.jar)
WARNING: Please consider reporting this to the maintainers of com.foo.bar.Server
WARNING: sun.misc.Unsafe::setMemory will be removed in a future release

449/466
MISC

450/466
JEP-472: Prepare to Restrict the Use
of JNI

Want integrity by default
–“[A]ll JDK features that are capable of breaking
integrity must obtain explicit approval from the
application's developer.”

451/466
JEP-472: Prepare to Restrict the Use
of JNI
1.
Long values as addresses in memory
2.
Byte buffers starting at address 0
3.
Modifying immutable objects (e.g., Strings)
4.
Writing past the end of an array
5.
Using functions disturbing the GC

452/466
JEP-472: Prepare to Restrict the Use
of JNI
1.
Long values as addresses in memory
void
Java_pkg_C_setPointerToThree__J
(jlong ptr) {
*
(
int
*
)ptr
=
3
;
}

453/466
JEP-472: Prepare to Restrict the Use
of JNI
2.
Byte buffers starting at address 0
return
(
*
env)
->
NewDirectByteBuffer
(env,
0
,
10
);

454/466
JEP-472: Prepare to Restrict the Use
of JNI
3.
Modifying immutable objects
jclass clazz
=
(
*
env)
->
FindClass
(env,
"java/lang/String"
);
jfieldID fid
=
(
*
env)
->
GetFieldID
(env, clazz ,
"value"
,
"[B"
);
jbyteArray contents
=
(jbyteArray)(
*
env)
->
GetObjectField
(env, str, fid);
jbyte b
=
0
;
(
*
env)
->
SetByteArrayRegion
(env, contents,
0
,
1
,
&
b);

455/466
JEP-472: Prepare to Restrict the Use
of JNI
4.
Writing past the end of an array jbyte
*
a
=
(
*
env)
->
GetPrimitiveArrayCritical
(env, arr,
0
);
a[
500
]
=
3
;
// May be out of bounds
(
*
env)
->
ReleasePrimitiveArrayCritical
(env, arr, a,
0
);

456/466
JEP-472: Prepare to Restrict the Use
of JNI
5.
Using functions disturbing the GC
“However, there are
significant restrictions on how
these functions can be used.”
https://shipilev.net/jvm/anatomy-quarks/9-jni-critical-gcl ocker/

457/466
JEP-472: Prepare to Restrict the Use
of JNI

“Under the policy of integrity by default, it is
the application developer (or perhaps
deployer, on the advice of the application
developer) who enables native access”

458/466
JEP-472: Prepare to Restrict the Use
of JNI

“Under the policy of integrity by default, it is
the application developer (or perhaps
deployer, on the advice of the application
developer) who enables native access”
WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::loadLibrary has been called by net.ptidej.newjava.restrictJNI.Main in module myModule (file:...)
WARNING: Use --enable-native-access=myModule to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled

459/466
JEP-479: Remove the Windows
32-bit x86 Port

“Allow contributors in the OpenJDK
Community to accelerate […] development”

“JEP 436 (Virtual Threads) for Windows x86-
32 falls back [on] kernel threads [removing
the] benefits of Project Loom.”

“Windows 10, the last Windows operating
system to support 32-bit operation, will reach
End of Life in October 2025.”

460/466
JEP-479: Remove the Windows
32-bit x86 Port

Also related to JEP-501: Deprecate the 32-
bit x86 Port for Removal
–Linux
32-bit x86 port

461/466
JEP-486: Permanently Disable the
Security Manager

“[T]he permission scheme is so complex that
the Security Manager has always been
disabled by default, and its use is […] rare.”

“From networking, I/O, and JDBC, to XML,
AWT, and Swing, the libraries must
implement the least-privilege model
in case
the Security Manager is enabled

Emphasis mine

462/466
JEP-486: Permanently Disable the
Security Manager

“[T]he permission scheme is so complex that
the Security Manager has always been
disabled by default, and its use is […] rare.”

“From networking, I/O, and JDBC, to XML,
AWT, and Swing, the libraries must
implement the least-privilege model
in case
the Security Manager is enabled

Emphasis mine

463/466
JEP-486: Permanently Disable the
Security Manager

“Over 1,000 methods must check for
permission”

“Over 1,200 methods must elevate their
privileges”

If needed, can be replaced outside of JVM
–An agent can block code from calling
System::exit

464/466
JEP-493: Linking Run-Time Images
without JMODs

“Reduce the size of the JDK by […] 25% by
enabling the jlinktool to create custom
run-time images without using the JDK's
JMOD files.”
–JMOD is JAR with native code, configuration
files, and other kinds of data

465/466

466/466
Image Credits 
Disclaimer: https://www.elitelux.club/understanding -java-programming/

Organisation: https://www.comsoftit.com/web.html

Java 5&6: https://www.amazon.ca/JAVA-SYNTHESE-COURS-EXERCICES-CORRIGES/dp/2744072192

Java 7: https://www.gizchina.com/2022/07/31/java-7- se-reaches-a-dead-end-java-8-becomes-the-norm/

Java 8: https://www.infoworld.com/article/3676578/o racle-unveils-performance-pack-for-java-8.html

Java 9: https://fossbytes.com/java-9-is-coming-rele ase-date-features/

Java 10: https://codepumpkin.com/java-10-features/

Java 11: https://www.amazon.ca/Mastering-Java-Second-Edward-Lavieri/dp/1789137616

Java 12: https://loiane.com/2019/03/what-is-new-in- java-12-api-for-developers/

https://www.neosoft.fr/nos-publications/blog-tech/b enchmark-java-introduction-a-jmh/

Java 13: https://java-13.com/

Java 14: https://dzone.com/refcardz/java-14-1

Java 15: https://dev.to/aaiezza/are-you-seriously-n ot-using-java-15-yet-5c86

Java 16: https://www.azul.com/blog/67-new-features- in-jdk-16/

Java 17: https://www.codingknownsense.com/clear-your-concept/java-17-a-brief-overview-of-features-and- enhancements/

Java 18: https://twitter.com/Sharat_Chander/status/ 1506279732094148627

Java 19: https://medium.com/codex/java-19-the-new-features-1bb1b6bed83c

https://wiki.openjdk.org/display/duke/Gallery

https://guigarage.com/

Java 20: https://dev.to/symflower/what-is-new-in-ja va-20-21gh

Java 21: https://www.unlogged.io/post/all-you-need- to-know-about-java21

Java 22: https://www.makb183.com/2023/10/java-22-what-to-expect.html

Eager: https://www.facebook.com/eagertolearnJava/

https://superacpov.live/product_details/50265612.ht ml

https://www.istockphoto.com/search/2/image?mediatype=illustration&phrase=warning+road+signs

Java 23: https://www.heise.de/news/Java-23-erweitert-Import-und-Patterns-verzichtet-aber-auf-String-Te mplates-9870591.html

Java 24: https://www.oracle.com/news/announcement/oracle-releases-java-24-2025-03-18/

https://tenor.com/en-GB/view/the-simpsons-homer-bush-disappear-awkward-gif-4841810