Slide 1

Slide 1 text

@stgerberding Eine Reise durch die JDKs Sandra Gerberding – smartsteuer GmbH

Slide 2

Slide 2 text

@stgerberding T ourguide Software-Entwicklerin: Java Web Anwendungen Continuous Integration Software-Architektur T witter: @stgerberding Blog: http://sandra.gerberding.blog E-Mail: [email protected] Speaker Deck: https://speakerdeck.com/sandrag Sandra Gerberding 2

Slide 3

Slide 3 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 3

Slide 4

Slide 4 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 4

Slide 5

Slide 5 text

@stgerberding JDK9 JShell Jigsaw Private methods in interfaces Immutable Collections … und mehr … 5

Slide 6

Slide 6 text

@stgerberding JDK 9 - Jigsaw module tax.calculation { exports de.gerberding.tax.calculation.api; } module tax.client { requires tax.calculation; } module tax.calculation module tax.client package …tax.calculation.implementation package …tax.calculation.api package …tax.client module-info.java module-info.java 6

Slide 7

Slide 7 text

@stgerberding JDK 9 - Jigsaw package de.gerberding.tax.calculation.api; import de.gerberding.tax.calculation.implementation.SimpleTaxCalculator; public interface TaxCalculator { double computeVAT (double netPrice, double vatRate); double computeGrossPrice (double netPrice, double vatRate); static TaxCalculator createSimpleTaxCalculator () { return new SimpleTaxCalculator (); } } package de.gerberding.tax.calculation.implementation; import de.gerberding.tax.calculation.api.TaxCalculator; public class SimpleTaxCalculator implements TaxCalculator { @Override public double computeVAT (final double netPrice, final double vatRate) { return (netPrice / 100) * vatRate; } @Override public double computeGrossPrice (final double netPrice, final double vatRate) { return netPrice + computeVAT (netPrice, vatRate); } } module tax.calculation { exports de.gerberding.tax.calculation.api; } 7

Slide 8

Slide 8 text

@stgerberding JDK 9 - Jigsaw public class TaxCalculatorClient { public static void main (final String[] args) { final TaxCalculator taxCalculator = new SimpleTaxCalculator (); final double vat = taxCalculator.computeVAT (15.95, 19.00); final double grossPrice = taxCalculator.computeGrossPrice (20.45, 7); System.out.println ("---------- Tax Calculator ——————"); System.out.println ("netPrice = 15.95 and vatRate = 19 => vat = " + vat); System.out.println ("netPrice = 20.45 and vatRate = 7 => grossPrice = " + grossPrice); } } module tax.client { requires tax.calculation; } public class TaxCalculatorClient { public static void main (final String[] args) { final TaxCalculator taxCalculator = TaxCalculator.createSimpleTaxCalculator (); final double vat = taxCalculator.computeVAT (15.95, 19.00); final double grossPrice = taxCalculator.computeGrossPrice (20.45, 7); System.out.println ("---------- Tax Calculator ------------"); System.out.println ("netPrice = 15.95 and vatRate = 19 => vat = " + vat); System.out.println ("netPrice = 20.45 and vatRate = 7 => grossPrice = " + grossPrice); } } 8

Slide 9

Slide 9 text

@stgerberding JDK 9 - JShell jshell> Pattern.compile("(\\d{2})\\.(\\d{2})\\.(\\d{4})"); $1 ==> (\d{2})\.(\d{2})\.(\d{4}) | created scratch variable $1 : Pattern jshell> $1.matcher("02.09.2020"); $2 ==> java.util.regex.Matcher[pattern=(\d{2})\.(\d{2})\.(\d{4}) region=0,10 lastmatch=] | created scratch variable $2 : Matcher jshell> $2.matches() $3 ==> true | created scratch variable $3 : boolean jshell> for (int group = 0; group <= $2.groupCount(); group++) { ...> System.out.println("group " + group + ": " + $2.group(group)); ...> } group 0: 02.09.2020 group 1: 02 group 2: 09 group 3: 2020 9

Slide 10

Slide 10 text

@stgerberding JDK 9 - JShell jshell> /list -all s1 : import java.io.*; s2 : import java.math.*; s3 : import java.net.*; s4 : import java.nio.file.*; s5 : import java.util.*; s6 : import java.util.concurrent.*; s7 : import java.util.function.*; s8 : import java.util.prefs.*; s9 : import java.util.regex.*; s10 : import java.util.stream.*; 1 : Pattern.compile("(\\d{2})\\.(\\d{2})\\.(\\d{4})"); 2 : $1.matcher("02.09.2020"); 3 : $2.matches() 4 : for (int group = 0; group <= $2.groupCount(); group++) { System.out.println("group " + group + ": " + $2.group(group)); } https://docs.oracle.com/javase/9/jshell/toc.htm 10

Slide 11

Slide 11 text

@stgerberding JDK 9 - Private Methods in Interfaces public interface UserService { boolean isAllowed (User user, Right right); default List getRights (final User user) { final List userRights = new ArrayList<>(); user.getRoles ().forEach ((Role role) -> { userRights.addAll(role.getRights()); }); return userRights; } } public interface UserService { boolean isAllowed (User user, Right right); default List getRights (final User user) { final List userRights = new ArrayList<>(); addAllUserRights (user, userRights); return userRights; } private void addAllUserRights (final User user, final List userRights) { user.getRoles ().forEach ((Role role) -> { userRights.addAll(role.getRights()); }); } } 11

Slide 12

Slide 12 text

@stgerberding JDK 9 - Immutable Collections final List immutableLanguages = List.of ("Groovy", "Kotlin", "Java"); final List languagesShort = Collections.unmodifiableList (Arrays.asList ("Groovy", "Kotlin", "Java")); final List languages = new ArrayList<>(); languages.add ("Groovy"); languages.add ("Kotlin"); languages.add ("Java"); final List unmodifiableLanguages = Collections.unmodifiableList (languages); final Map starTrekVessels = new HashMap<>(); starTrekVessels.put (STAR_TREK, "NCC-1701"); starTrekVessels.put (STAR_TREK_NG, "NCC-1701-D"); starTrekVessels.put (STAR_TREK_VOYAGER, "NCC-74656"); starTrekVessels.put (STAR_TREK_DS9, "NX-74205"); final Map unmodifiableVessels = Collections.unmodifiableMap (starTrekVessels); final Map immutableVessels = Map.of (STAR_TREK, "NCC-1701", STAR_TREK_NG, "NCC-1701-D", STAR_TREK_VOYAGER, "NCC-74656", STAR_TREK_DS9, "NX-74205"); JDK 8 JDK 9 JDK 8 JDK 9 List Map 12

Slide 13

Slide 13 text

@stgerberding JDK 9 … und mehr … - 2 neue Interfaces im Process API - java.jang.ProcessHandle - Java.jang.ProcessHandleInfo - Verbesserung von try with Resources - Completable Future API - Support delays and timeouts - Unicode 8 - String Optimierung (Speicherplatz) - JavaDoc erzeugt HTML 5 - Unterstützung von PKC512 in Keystores - Diamond Operator in anonymen Classes - Und mehr … https://docs.oracle.com/javase/9/whatsnew/toc.htm 13

Slide 14

Slide 14 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 14

Slide 15

Slide 15 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 15

Slide 16

Slide 16 text

@stgerberding JDK10 Reserved T ype „var“ Release Docker Support Collections … und mehr … 16

Slide 17

Slide 17 text

@stgerberding JDK 10 - Reserved T ype „var“ public class VarDemo { final var memberVariable = "Wej Qap!"; public static void main (final String[] args) { var localVariable; // QoHbe' SuS! String var; var personsVar = new ArrayList<>(); // ArrayList != List List persons = new ArrayList<>(); var authorVar = getAuthor (); // Return value: Person? Author? …? Person author = getAuthor (); } } var message = "Hello World!"; // String message = "Hello World!"; message = 1234; var person = new Person ("Gene", "Roddenberry"); 17

Slide 18

Slide 18 text

@stgerberding JDK 10 - Docker Support Host RAM Docker Container RAM JVM in Docker Container RAM 32 GByte 6 GByte 8 GByte Standard Wert 25% des Hosts Vor JDK 10 JVM in Docker Container RAM 1,5 GByte Standard Wert 25% des Docker Containers Ab JDK 10 Aus Designgründen sind die Größen nicht proportional dargestellt. 18

Slide 19

Slide 19 text

@stgerberding JDK 10 - Docker Support Host CPUs Docker Container CPUs JVM in Docker Container CPUs 6 CPUs 3 CPUs 6 CPUs Standard Wert 100% des Hosts Vor JDK 10 JVM in Docker Container RAM 3 CPUs Standard Wert 100% des Docker Containers Ab JDK 10 19

Slide 20

Slide 20 text

@stgerberding JDK 10 - Collections final List names = getNames (); final List immutableCopyOfNames = List.copyOf (names); System.out.println ("immutableCopyOfList type: " + immutableCopyOfNames.getClass ()); final Set colors = getColors (); final Set immutableCopyOfColors = Set.copyOf (colors); System.out.println ("immutableCopyOfSet type: " + immutableCopyOfColors.getClass ()); final Map personAgeMapping = getPersonsAge (); final Map immutableCopyOfMap = Map.copyOf (personAgeMapping); System.out.println ("immutableCopyOfMap type: " + immutableCopyOfMap.getClass ()); final List immutableNames = names.stream ().collect (Collectors.toUnmodifiableList ()); System.out.println ("immutableNames type: " + immutableNames.getClass ()); immutableCopyOfList type: class java.util.ImmutableCollections$ListN immutableCopyOfSet type: class java.util.ImmutableCollections$SetN immutableCopyOfMap type: class java.util.ImmutableCollections$MapN immutableNames type: class java.util.ImmutableCollections$ListN Console 20

Slide 21

Slide 21 text

@stgerberding JDK 10… und mehr … - Optional Erweiterung - Optional.orElseThrow () - JavaDoc Erweiterungen (css ..) - javah entfernt - Und mehr … https://www.oracle.com/java/technologies/javase/10-relnote-issues.html 21

Slide 22

Slide 22 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 22

Slide 23

Slide 23 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 23

Slide 24

Slide 24 text

@stgerberding JDK11 L TS API Änderungen JCMD / Flight Recorder HTTP Client Collections … und mehr … 24

Slide 25

Slide 25 text

@stgerberding JDK 11 - JCMD/Flight Recorder sandragerberding@MacBook-Pro demo % jcmd 18743 VM.flags 18743: -XX:-BytecodeVerificationLocal -XX:-BytecodeVerificationRemote -XX:CICompilerCount=12 -XX:ConcGCThreads=3 -XX:G1ConcRefinementThreads=13 -XX:G1HeapRegionSize=4194304 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=1073741824 -XX:+ManagementServer -XX:MarkStackSize=4194304 -XX:MaxHeapSize=17179869184 -XX:MaxNewSize=10305404928 -XX:MinHeapDeltaBytes=4194304 -XX:NonNMethodCodeHeapSize=12163472 -XX:NonProfiledCodeHeapSize=239494768 -XX:ProfiledCodeHeapSize=0 -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:TieredStopAtLevel=1 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC 25

Slide 26

Slide 26 text

@stgerberding JDK 11 - JCMD/Flight Recorder 26

Slide 27

Slide 27 text

@stgerberding JDK 11 - JCMD/Flight Recorder 27

Slide 28

Slide 28 text

@stgerberding JDK 11 - String - API Änderungen System.out.println ("Character: " + Character.toString (65)); System.out.println ("•".repeat (20)); final String blank = " "; System.out.println ("'" + blank + "'.isBlank: " + blank.isBlank ()); System.out.println ("'" + blank + "'.isEmpty: " + blank.isEmpty ()); System.out.println ("•".repeat (20)); final String string = " \u205Fnaked\u205F "; System.out.println ("strip String: '" + string.strip () + "'"); System.out.println ("trim String: '" + string.trim () + "'"); System.out.println ("•".repeat (20)); "a\nb\nc\nd\ne\nf".lines ().forEach (line -> System.out.println ("line = " + line)); Character: A •••••••••••••••••••• ' '.isBlank: true ' '.isEmpty: false •••••••••••••••••••• strip String: 'naked' trim String: ' naked ' •••••••••••••••••••• line = a line = b line = c 28

Slide 29

Slide 29 text

@stgerberding JDK 11 - HTTP Client final URL url = new URL ("https://swapi.dev/api/planets/2/"); final HttpURLConnection connection = (HttpURLConnection) url.openConnection (); connection.setRequestMethod ("GET"); connection.setRequestProperty ("Accept", "application/json"); final int responseCode = connection.getResponseCode (); final Map> headers = connection.getHeaderFields (); final BufferedReader in = new BufferedReader (new InputStreamReader (connection.getInputStream ())); String inputLine; final StringBuilder responseBody = new StringBuilder (); while ((inputLine = in.readLine ()) != null) { responseBody.append (inputLine); } in.close (); connection.disconnect (); System.out.println ("Status: " + responseCode); System.out.println ("Body: " + responseBody); System.out.println ("Headers: " + headers); JDK 8 altes API 29

Slide 30

Slide 30 text

@stgerberding final URI uri = new URI ("https://swapi.dev/api/planets/1/"); final HttpRequest request = HttpRequest.newBuilder (uri).GET ().build (); final HttpResponse.BodyHandler bodyHandler = HttpResponse.BodyHandlers.ofString (); final HttpClient httpClient = HttpClient.newBuilder ().build (); final HttpResponse response = httpClient.send (request, bodyHandler); final int responseCode = response.statusCode (); final String responseBody = response.body (); final HttpHeaders headers = response.headers (); System.out.println ("Status: " + responseCode); System.out.println ("Body: " + responseBody); System.out.println ("Headers: " + headers.map ()); JDK 11 - HTTP Client JDK 11 neues API 30

Slide 31

Slide 31 text

@stgerberding JDK 11… und mehr … - T ransport Layer Security (TLS) 1.3 - „var“ Erweiterung - auch als Lambda Parameter - Unicode 10 - Applet, JavaFX … nicht mehr Bestandteil vom JDK 11 - Und mehr … https://www.oracle.com/java/technologies/javase/jdk-11-relnote.html 31

Slide 32

Slide 32 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 32

Slide 33

Slide 33 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 33

Slide 34

Slide 34 text

@stgerberding JDK12 Switch Expression … und mehr … Preview 34

Slide 35

Slide 35 text

@stgerberding JDK 12 … und mehr … - Kleine Änderungen - Unicode 11 https://www.oracle.com/java/technologies/javase/12-relnote-issues.html 35

Slide 36

Slide 36 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 36

Slide 37

Slide 37 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 37

Slide 38

Slide 38 text

@stgerberding JDK13 Switch Expression T ext Blocks … und mehr … Preview Preview 38

Slide 39

Slide 39 text

@stgerberding JDK 13 … und mehr … - FileSystems API hat 3 neue Methods - newFileSystem(Path) - newFileSystem(Path, Map) - newFileSystem(Path, Map, ClassLoader) - Unicode 12.1 - Und mehr … https://www.oracle.com/java/technologies/javase/13-relnote-issues.html 39

Slide 40

Slide 40 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 40

Slide 41

Slide 41 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 41

Slide 42

Slide 42 text

@stgerberding JDK14 Switch Expression Records … und mehr … Preview 42

Slide 43

Slide 43 text

@stgerberding JDK 14 - Switch Expressions public String findGalaxyQuadrant (final Species species) { String quadrant; switch (species) { case KLINGONS: case ROMULANS: quadrant = "Beta quadrant"; break; case FERENGI: case VULCANS: case HUMANS: quadrant = "Alpha quadrant"; break; default: quadrant = "unknown quadrant"; break; } return quadrant; } public String findGalaxyQuadrant (final Species species) { String quadrant; switch (species) { case KLINGONS, ROMULANS -> quadrant = "Beta quadrant"; case FERENGI, VULCANS, HUMANS -> quadrant = "Alpha quadrant"; default -> quadrant = "unknown quadrant"; } return quadrant; } public String findGalaxyQuadrant (final Species species) { return switch (species) { case KLINGONS, ROMULANS -> "Beta quadrant"; case FERENGI, VULCANS, HUMANS -> "Alpha quadrant"; default -> "unknown quadrant"; }; } enum Species { KLINGONS, ROMULANS, FERENGI, VULCANS, HUMANS, BORG } Classic Switch Statement New Switch Statement New Switch Expression 43

Slide 44

Slide 44 text

@stgerberding JDK 14 - Switch Expressions public String findGalaxyQuadrant (final Species species) { switch (species) { case KLINGONS, ROMULANS -> { return "Beta quadrant"; } case FERENGI, VULCANS, HUMANS -> { return "Alpha quadrant"; } default -> { return "unknown quadrant"; } } } public int computeNumberOfIndividuals (final Species species) { return switch (species) { case KLINGONS -> { final int individualsAlpha = calculateIndividualsPerQuadrant (KLINGONS, "Alpha"); final int individualsBeta = calculateIndividualsPerQuadrant (KLINGONS, "Beta"); yield individualsAlpha + individualsBeta; } case HUMANS -> calculateIndividualsPerQuadrant (HUMANS, "Alpha"); default -> 0; }; } New Switch Statement with return New Switch Expression with yield 44

Slide 45

Slide 45 text

@stgerberding JDK 14 … und mehr … - Detaillierte NullPointerException Message mit JVM Option aktivierbar - TLS Erweiterungen - Und mehr … https://www.oracle.com/java/technologies/javase/14-relnote-issues.html 45

Slide 46

Slide 46 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 46

Slide 47

Slide 47 text

@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK 12 JDK 13 JDK 14 47

Slide 48

Slide 48 text

@stgerberding JDK15 Sealed T ypes Records Pattern Matching for instanceof T ext Blocks … und mehr … Preview Preview Preview 48

Slide 49

Slide 49 text

@stgerberding JDK 15 - T ext Blocks final String exampleText = "Das ist ein\n" + " \"Beispiel\" Text!\n" + "Das ist ein etwas längerer Text und ich möchte ihn nur in der 'IDE' umbrechen. "; final String exampleText = """ Das ist ein "Beispiel" Text! Das ist ein etwas längerer Text \ und ich möchte ihn nur in der 'IDE' umbrechen. \s"""; 'Das ist ein "Beispiel" Text! Das ist ein etwas längerer Text und ich möchte ihn nur in der 'IDE' umbrechen. ' Console 49

Slide 50

Slide 50 text

@stgerberding JDK 15 … und mehr … - CharSequence Erweiterung - Default Method CharSequence.isEmpty () - Hidden Classes - Unicode 13.0 - Nashorn Engine ist nicht mehr Bestandteil es JDKs - TLS Erweiterungen - Und mehr … https://jdk.java.net/15/release-notes 50

Slide 51

Slide 51 text

@stgerberding Vielen Dank fürs Zuhören! Zeichnungen: Sandra Gerberding 51

Slide 52

Slide 52 text

@stgerberding Bonus Folien Zeichnungen: Sandra Gerberding 52

Slide 53

Slide 53 text

@stgerberding HttpResponse response = HttpClient.newBuilder() .authenticator(new Authenticator () { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( "username", "password".toCharArray()); } }).build() .send(request, HttpResponse.BodyHandlers.ofString ()); CompletableFuture> response3 = HttpClient.newBuilder() .build() .sendAsync(request, HttpResponse.BodyHandlers.ofString()); JDK 11 - HTTP Client Connection mit Authenticator HttpClient.newBuilder ().build ().sendAsync (request, HttpResponse.BodyHandlers.ofString ()) .thenApply (response -> { System.out.println (response.statusCode ()); return response; }) .thenApply (HttpResponse::body) .thenAccept (System.out::println); Asynchronous Connection 53

Slide 54

Slide 54 text

@stgerberding public record Cube (int height, int width, int depth) { } public final class Cube { private final int height; private final int width; private final int depth; public Cube (int height, int width, int depth) { this.height = height; this.width = width; this.depth = depth; } public int getHeight () { return height; } public int getWidth () { return width; } public int getDepth () { return depth; } @Override public boolean equals (Object o) { if (this == o) return true; if (o == null || getClass () != o.getClass ()) { return false; } Cube cube = (Cube) o; return height == cube.height && width == cube.width && depth == cube.depth; } @Override public int hashCode () { return Objects.hash (height, width, depth); } @Override public String toString () { return "Cube {" + "height=" + height + ", width=" + width + ", depth=" + depth + '}'; } } JDK 15 - Records Preview Syntax Struktur 54

Slide 55

Slide 55 text

@stgerberding public record Cube (int height, int width, int depth) implements Body { private final static int DENSITY = 3; public Cube () { this (1, 1, 1); } @Override public int volume () { return height () * width () * depth (); } } JDK 15 - Records Preview Syntax 55