Share
Embed
CyberLand-11-2020
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
-Reservierter Typ "var"
- Erweiterung der Collections
- HttpClient/HttpRequest neues FluentAPI
- Switch Expressions
- Erweiterung der String-Klasse
- Records
Diese werden zum Teil anhand von Quelltext-Beispielen veranschaulicht.
Ich wünsche Euch eine gute Reise.
P.S.: Bringt festes Schuhwerk mit.
Sandra Warmbrunn
December 03, 2020
Transcript
57 slides
-
@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 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 3 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 4 -
@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 -
@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 { @Overrid e public double computeVAT (final double netPrice, final double vatRate) { return (netPrice / 100) * vatRate ; } @Overrid e public double computeGrossPrice (final double netPrice, final double vatRate) { return netPrice + computeVAT (netPrice, vatRate) ; } } module tax.calculation { exports de.gerberding.tax.calculation.api ; } 7 -
@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 -
@stgerberding JDK 9 - JShell jshell> Pattern.compile("(\\d{2})\\.(\\d{2})\\.(\\d{4})") ; $1 ==>
(\d{2})\.(\d{2})\.(\d{4} ) | created scratch variable $1 : Patter n 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 : Matche r jshell> $2.matches( ) $3 ==> tru e | created scratch variable $3 : boolea n jshell> for (int group = 0; group <= $2.groupCount(); group++) { ...> System.out.println("group " + group + ": " + $2.group(group)) ; ...> } group 0: 02.09.202 0 group 1: 0 2 group 2: 0 9 group 3: 2020 9 -
@stgerberding JDK 9 - JShell jshell> /list -al l 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 -
@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 -
@stgerberding JDK 9 - Immutable Collections final List<String> immutableLanguages =
List.of ("Groovy", "Kotlin", "Java"); final List<String> languagesShort = Collections.unmodifiableLis t (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 -
@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 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 14 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 15 -
@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 -
@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 -
@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 CPUs 3 CPUs Standard Wert 100% des Docker Containers Ab JDK 10 19 -
@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$List N immutableCopyOfSet type: class java.util.ImmutableCollections$Set N immutableCopyOfMap type: class java.util.ImmutableCollections$Map N immutableNames type: class java.util.ImmutableCollections$ListN Console 20 -
@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 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 22 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 23 -
@stgerberding JDK11 L TS API Änderungen JCMD / Flight
Recorder HTTP Client Collections … und mehr … 24 -
@stgerberding JDK 11 - JCMD/Flight Recorder sandragerberding@MacBook-Pro demo % jcmd
18743 VM.flag s 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 -
@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: tru e ' '.isEmpty: fals e ••••••••••••••••••• • strip String: 'naked ' trim String: ' naked ' ••••••••••••••••••• • line = a line = b line = c 28 -
@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 -
@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 -
@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 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 32 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 33 -
@stgerberding JDK 12 … und mehr … - Kleine Änderungen
- Unicode 11 https://www.oracle.com/java/technologies/javase/12-relnote-issues.html 35 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 36 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 37 -
@stgerberding JDK13 Switch Expression T ext Blocks … und mehr
… Preview Preview 38 -
@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 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 40 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 41 -
@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, BOR G } Classic Switch Statement New Switch Statement New Switch Expression 43 -
@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 -
@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 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 46 -
@stgerberding JDK 8 JDK 9 JDK 10 JDK 11 JDK
12 JDK 13 JDK 14 47 -
@stgerberding JDK15 Records Pattern Matching for instanceof T ext Blocks
… und mehr … Preview Preview 48 -
@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 ei n "Beispiel" Text ! Das ist ein etwas längerer Text \ und ich möchte ihn nur in der 'IDE' umbrechen. \s"""; 'Das ist ei n "Beispiel" Text ! Das ist ein etwas längerer Text und ich möchte ihn nur in der 'IDE' umbrechen. ' Console 49 -
@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 ; } @Overrid e 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 ; } @Overrid e public int hashCode () { return Objects.hash (height, width, depth) ; } @Overrid e public String toString () { return "Cube {" + "height=" + height + ", width=" + width + ", depth=" + depth + '}' ; } } JDK 15 - Records Preview Syntax Struktur 50 -
@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 ; } @Overrid e 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 ; } @Overrid e public int hashCode () { return Objects.hash (height, width, depth) ; } @Overrid e public String toString () { return "Cube {" + "height=" + height + ", width=" + width + ", depth=" + depth + '}' ; } } JDK 15 - Records Preview Syntax Struktur 51 -
@stgerberding public record Cube (int height, int width, int depth)
implements Body { private final static int DENSITY = 3 ; public Cube () { this (1, 1, 1) ; } @Overrid e public int volume () { return height () * width () * depth () ; } } JDK 15 - Records Preview Syntax 52 -
@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://www.oracle.com/java/technologies/javase/15-relnote-issues.html 53 -
@stgerberding Ausblick JDK 16 - Migrate from Mercurial to git
- Migrate to GitHub - Pattern Matching of instanceof - Records - Sealed Classes (Second Preview) - Und mehr … http://openjdk.java.net/projects/jdk/16/ 54 -
@stgerberding HttpResponse<String> response = HttpClient.newBuilder( ) .authenticator(new Authenticator () {
@Overrid e 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 57