Daily Java 21

Java Software Engineer

Line of Business Public

Merlin Bögershausen / @mboegie

Entry Poll

400
Mentimeter https://www.menti.com/aljvomg56fse

Mentimeter.com:

Release Cycle

VersionGA πŸŽ‰Free πŸ‘Extended πŸ’Ά

8

2014

Azul 2030

Oracle 2030

11

2018

Amazon 2027

Azul 2026

17

2019

Azul 2029

Oracle 2029

21

2023

2028

Oracle 2031

Mentimeter.com: 5520 4780

Feature pace

release and features

Mentimeter.com: 5520 4780

Results

700

State of 11

500

Features

  • Streams

  • Lambdas

  • Optional

  • Collection Factory Methods

Map.of("Vanessa", "πŸ‘§πŸ»", "Fred", "πŸ‘ΆπŸΌ", "Merlin", "πŸ§™β€β™‚οΈ")
    .entrySet().stream()
    .filter(e -> e.getKey().contains("e"))
    .findAny()
    .map(e -> e.getKey() + " is " + e.getValue())
    .ifPresent(System.out::println);

…​ more features …​

  • Local Variable Type Inference

  • HTTP Client

  • try-with-Resource

  • private Interface Methods

var client = HttpClient.newBuilder()
    .version(HttpClient.Version.HTTP_2)
    .authenticator(Authenticator.getDefault()).build();
var req = HttpRequest.newBuilder()
    .GET().uri(URI.create("http://localhost:8080"))
    .build();
var res = client.send(req, HttpResponse.BodyHandlers.ofString());

…​ more features …​

  • Local Variable Type Inference

  • HTTP Client

  • try-with-Resource

  • private Interface Methods

var res = client.send(req, HttpResponse.BodyHandlers.ofString());
try(var in = new ByteArrayInputStream(res.body().getBytes())) {
    var byteContent = Arrays.toString(in.readAllBytes());
    System.out.println(byteContent);
} catch (IOException e) {
    System.out.println("Failed to read response");
}

…​ that’s it.

java -XX:StartFlightRecording\
  -add-modules java.base Example.java

11 to 17

550

Java 12

Java 13

Java 14

Java 15

Java 16

Java 17

Overall State of 17

500

Most Awesome

  • Sealed class and Records

  • Type Pattern & Switch Expression

  • Helpful Null

  • Text Blocks

  • JPackage

Types

  • Sealed Class & Interfaces

  • Records

sealed interface Shape {
  record Cornered(int x, int y, int h, int w)
    implements Shape {}
  non-sealed interface Round implements Shape {}
  final class Weirdo implements Shape {}
}

Flow Control

  • Type Pattern

  • Switch Expression

switch (s) {
  case Triangle t when t.calculateArea() > 100 ->
    System.out.println("Large");
  case Triangle t -> System.out.println("Small");
  default -> System.out.println("Non-triangle");
}

Utilities

  • Helpful Nullpointer Exceptions

  • Textblocks

  • JPackage

Exception in thread "main" java.lang.NullPointerException:
        Cannot read field "c" because "a.b" is null
    at Prog.main(Prog.java:5)

Utilities

  • Helpful Nullpointer Exceptions

  • Textblocks

  • JPackage

String helloWorldResponse = String.format(
    """
    <html>
        <body>
            <p>Hello, %s</p>
        </body>
    </html>
    """, getName());

Utilities

  • Helpful Nullpointer Exceptions

  • Textblocks

  • JPackage

jpackage --type app-image\
  -i inputDir -n name
  --main-class className --main-jar\
  myJar.jar

17 to 20

550

Java 18

Java 19

  • Record Patterns πŸ”¬

  • Foreign Function & Memory API πŸ”¬

  • Virtual Threads πŸ”¬

  • Structured Concurrency πŸ”¬2

Java 20

  • Scoped Values πŸ”¬2

something big is coming!

The risky Part: Java 21

400

Targeted

Candidates

Drafts

How does it Look?

BeispielKlasssenDiagramm

Domain Modeling

sealed interface Kunde permits Businesskunde, Privatkunde
  { String name(); String mail(); }

record Privatkunde(String name, String mail)
  implements Kunde {}

record Businesskunde(String name, String mail,
  boolean isVorsteuerAbzugsberechtigt) implements Kunde {}

Flow Control

static double calculateMwSt(Kunde kunde, double wert) {
  return switch (kunde) {
    case Businesskunde b when b.isVorsteuerAbzugsberechtigt()
        -> 0.0d;
    case Businesskunde b -> wert * 0.18d;
    case Privatkunde p -> wert * 0.18d;
  };
}

Deconstruction

switch (rechnung) {
  case InterneVerechnung(var abt, double wert) ->
    Dummy.storeInDB(abt, wert);
  case ExternVersandt(Kunde kunde, var wert) -> {
    double mwst = calculateMwSt(kunde, wert);
    var txt = formatMail(kunde.name(), wert, mwst);
    Dummy.sendViaMail(kunde.mail(), txt);
  }
}

String interpolation

String mailText = """
Hallo %s, Bitte senden Sie uns den Rechnungsbetrag in HΓΆhe
von %.2f€ plus %.2f€ MwSt.

Mit freundlichen Grüßen
    Merlin BΓΆgershausen
""".formatted(name, wert, mwst);

Concurrency

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
  var future1 = executor.submit(() -> fetchURL(url1));
  var future2 = executor.submit(() -> fetchURL(url2));
  response.send(future1.get() + future2.get());
} catch (ExecutionException | InterruptedException e) {
  response.fail(e);
}

Final Thoughts

400

10 Releases with πŸ’―JEPs

OpenJDK.org as Baseline
Dev.java for learning

Path into Future

CloudSurfDuke

Contact

Me

@MBoegi // MBoegers

adesso

Infos // DevBlog

See you!

IMG 1302

Image Credits