Eine Reise durch die JDKs

Eine Reise durch die JDKs

Viele von Euch, so wie ich, arbeiten im Job noch mit JDK 8. Daher möchte ich Euch mitnehmen auf die Reise durch die JDKs. Wir starten unsere Reise bei JDK 8 und wandern bis zur aktuellen Version. Außerdem wagen wir einen Blick auf die Attraktionen der zukünftigen Versionen.
Wir halten unter anderem an folgenden Stationen:
- JShell
- Private Methods in Interfaces
- Optional class
- Schlüsselwort "var"
- Erweiterung der Collections
- HttpClient/HttpRequest neues FluentAPI
- Switch Expressions
- Erweiterung der String-Klasse

Diese werden zum Teil anhand von Quelltext-Beispielen veranschaulicht.
Ich wünsche Euch eine gute Reise.

P.S.: Bringt festes Schuhwerk mit.

93775dfd8e4f0078d4b724a622d734d7?s=128

Sandra Gerberding

September 02, 2020
Tweet

Transcript

  1. @stgerberding Eine Reise durch die JDKs Sandra Gerberding – smartsteuer

    GmbH
  2. @stgerberding T ourguide Software-Entwicklerin: Java Web Anwendungen Continuous Integration Software-Architektur

    T witter: @stgerberding Blog: http://sandra.gerberding.blog E-Mail: sandra.gerberding@smartsteuer.de Speaker Deck: https://speakerdeck.com/sandrag Sandra Gerberding 2
  3. @stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK

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

    12 JDK 13 JDK 14 4
  5. @stgerberding JDK9 JShell Jigsaw Private methods in interfaces Immutable Collections

    … und mehr … 5
  6. @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
  7. @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
  8. @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
  9. @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
  10. @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
  11. @stgerberding JDK 9 - Private Methods in Interfaces public interface

    UserService { boolean isAllowed (User user, Right right); default List<Right> getRights (final User user) { final List<Right> 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<Right> getRights (final User user) { final List<Right> userRights = new ArrayList<>(); addAllUserRights (user, userRights); return userRights; } private void addAllUserRights (final User user, final List<Right> userRights) { user.getRoles ().forEach ((Role role) -> { userRights.addAll(role.getRights()); }); } } 11
  12. @stgerberding JDK 9 - Immutable Collections final List<String> immutableLanguages =

    List.of ("Groovy", "Kotlin", "Java"); final List<String> languagesShort = Collections.unmodifiableList (Arrays.asList ("Groovy", "Kotlin", "Java")); final List<String> languages = new ArrayList<>(); languages.add ("Groovy"); languages.add ("Kotlin"); languages.add ("Java"); final List<String> unmodifiableLanguages = Collections.unmodifiableList (languages); final Map<Series, String> 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<Series, String> unmodifiableVessels = Collections.unmodifiableMap (starTrekVessels); final Map<Series, String> 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
  13. @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
  14. @stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK

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

    12 JDK 13 JDK 14 15
  16. @stgerberding JDK10 Reserved T ype „var“ Release Docker Support Collections

    … und mehr … 16
  17. @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<Object> != List<Person> List<Person> 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
  18. @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
  19. @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
  20. @stgerberding JDK 10 - Collections final List<String> names = getNames

    (); final List<String> immutableCopyOfNames = List.copyOf (names); System.out.println ("immutableCopyOfList type: " + immutableCopyOfNames.getClass ()); final Set<String> colors = getColors (); final Set<String> immutableCopyOfColors = Set.copyOf (colors); System.out.println ("immutableCopyOfSet type: " + immutableCopyOfColors.getClass ()); final Map<String, Long> personAgeMapping = getPersonsAge (); final Map<String, Long> immutableCopyOfMap = Map.copyOf (personAgeMapping); System.out.println ("immutableCopyOfMap type: " + immutableCopyOfMap.getClass ()); final List<String> 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
  21. @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
  22. @stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK

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

    12 JDK 13 JDK 14 23
  24. @stgerberding JDK11 L TS API Änderungen JCMD / Flight Recorder

    HTTP Client Collections … und mehr … 24
  25. @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
  26. @stgerberding JDK 11 - JCMD/Flight Recorder 26

  27. @stgerberding JDK 11 - JCMD/Flight Recorder 27

  28. @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
  29. @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<String, List<String>> 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
  30. @stgerberding final URI uri = new URI ("https://swapi.dev/api/planets/1/"); final HttpRequest

    request = HttpRequest.newBuilder (uri).GET ().build (); final HttpResponse.BodyHandler<String> bodyHandler = HttpResponse.BodyHandlers.ofString (); final HttpClient httpClient = HttpClient.newBuilder ().build (); final HttpResponse<String> 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
  31. @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
  32. @stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK

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

    12 JDK 13 JDK 14 33
  34. @stgerberding JDK12 Switch Expression … und mehr … Preview 34

  35. @stgerberding JDK 12 … und mehr … - Kleine Änderungen

    - Unicode 11 https://www.oracle.com/java/technologies/javase/12-relnote-issues.html 35
  36. @stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK

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

    12 JDK 13 JDK 14 37
  38. @stgerberding JDK13 Switch Expression T ext Blocks … und mehr

    … Preview Preview 38
  39. @stgerberding JDK 13 … und mehr … - FileSystems API

    hat 3 neue Methods - newFileSystem(Path) - newFileSystem(Path, Map<String, ?>) - newFileSystem(Path, Map<String, ?>, ClassLoader) - Unicode 12.1 - Und mehr … https://www.oracle.com/java/technologies/javase/13-relnote-issues.html 39
  40. @stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK

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

    12 JDK 13 JDK 14 41
  42. @stgerberding JDK14 Switch Expression Records … und mehr … Preview

    42
  43. @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
  44. @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
  45. @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
  46. @stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK

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

    12 JDK 13 JDK 14 47
  48. @stgerberding JDK15 Sealed T ypes Records Pattern Matching for instanceof

    T ext Blocks … und mehr … Preview Preview Preview 48
  49. @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
  50. @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
  51. @stgerberding Vielen Dank fürs Zuhören! Zeichnungen: Sandra Gerberding 51

  52. @stgerberding Bonus Folien Zeichnungen: Sandra Gerberding 52

  53. @stgerberding HttpResponse<String> response = HttpClient.newBuilder() .authenticator(new Authenticator () { @Override

    protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( "username", "password".toCharArray()); } }).build() .send(request, HttpResponse.BodyHandlers.ofString ()); CompletableFuture<HttpResponse<String>> 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
  54. @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
  55. @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