Changelog Java Versions

Eine Auflistung der Änderungen in Java aus Sicht eines Entwickler

Erstellt von Frank Rahn

Abstrakt

Die Programmiersprache Java entwickelt sich von Version zu Version weiter. In dieser Präsentation werden die wichtigsten Änderungen aus Sicht eine Entwicklers dargestellt.

Es werden Programmierkenntnisse ab der Java Version 7 vorausgesetzt.

Tastenkombinationen

  • Space oder N springt zur nächsten Folie
  • P springt zur vorherigen Folie
  • F zeigt die Präsentation im Vollbildmodus
  • B zeigt die Pause Folie
  • Esc oder O zeigt die Übersicht der Folien
  • S wird die Speakers-Ansicht gestartet

Über mich

Kontakt

Frank Rahn
Frank Rahn
Twitter

Zur Person

Seit 1992 arbeite ich als freiberuflicher unabhängiger Softwarearchitekt und -consultant.

Seitdem beschäftige ich mich mit dem Entwurf und der Realisierung von Anwendungen und verfüge über umfangreiche Erfahrungen in der Integration von Anwendungen.

Meine Einsatzbereiche

  • Softwarearchitekturen mit Java-Technologien
    • mit Spring Framework, Boot, Batch, …
  • Integration von unternehmensübergreifenden IT-Systemen
    • per REST, SOAP, …
  • Entwicklung von großen und komplexen Systemen
  • Performance-Analysen mit entsprechender Optimierung

Java 8

Informationen

Release im März 2014

Ist eine LTS-Version

Support Ende im Januar 2019

https://openjdk.java.net/projects/jdk8/features

Die wichtigsten Änderungen

  • Lambda
  • Default und statische Methoden in Interfaces
  • Stream API
  • Bulk Operations auf Collections
  • Date-Time API
  • ...

Lambda und Methodenreferenz


            package java8;

            import java.util.List;

            public class Lambda {

              public void printList1(List<String> strings) {
                strings.forEach(
                  s -> {
                    System.out.println(s);
                  }
                );
              }

              public void printList2(List<String> strings) {
                strings.forEach(System.out::println);
              }
            }
          

Default und statische Methoden in Interfaces


            package java8;

            public interface DefaultStaticMethod {

              void abstractMethod();

              default void defaultMethod() {
                System.out.println("Call defaultMethod");
                abstractMethod();
              }

              static void staticMethod() {
                System.out.println("Call staticMethod");
              }
            }
          

Default und statische Methoden in Interfaces


            package java8;

            public class DefaultStaticMethodImpl implements DefaultStaticMethod {

              @Override
              public void abstractMethod() {
                System.out.println("Call abstractMethod");
                DefaultStaticMethod.staticMethod();
              }
            }
          

Stream API


            package java8;

            import java.util.stream.IntStream;
            import java.util.stream.LongStream;
            import java.util.stream.Stream;

            public class Streams {

              public void process() {
                Stream<String> streamEmpty = Stream.empty();
                Stream<String> streamOfArray = Stream.of("a", "b", "c");
                Stream<String> streamIterated =
                  Stream.iterate(40, n -> n + 2).limit(20);
                IntStream intStream = IntStream.range(1, 3);
                LongStream longStream = LongStream.rangeClosed(1, 3);
              }
            }
          

Bulk Operations auf Collections


            package java8;

            import java.util.List;

            public class BulkOperation {

              public long process(List<String> strings) {
                return
                  strings
                    .stream()
                      .filter(s -> s.startsWith("test"))
                      .sorted()
                      .map(String::length)
                      .count();
              }
            }
          

Date-Time API


            package java8;

            import java.time.LocalDate;
            import java.time.LocalDateTime;

            public class DateTime {

              public boolean process() {
                LocalDate birthday = LocalDate.of(1967, 5, 5);
                LocalTime now = LocalTime.now();

                LocalDateTime today = LocalDateTime.now();
                LocalDateTime tomorrow = today.plusDays(1);

                return tomorrow.isAfter(today);
              }
            }
          

Java 9

Informationen

Release im September 2017

Support Ende im März 2018

https://openjdk.java.net/projects/jdk9

Die wichtigsten Änderungen

  • PKCS12
  • Modulsystem
  • JShell
  • Convenience Factory Methods for Collections
  • Erweiterung Optional
  • Private Methoden in Interfaces
  • Process API
  • Flow API
  • Stream API
  • ...

Modulsystem


            module changelog.java.version.java8 {
              exports java8;
            }
          

            module changelog.java.version.java9 {
              requires changelog.java.version.java8;

              exports java9;
            }
          

JShell


            $ jshell
            |  Welcome to JShell -- Version 11.0.8
            |  For an introduction type: /help intro

            jshell> 1 + 2
            $1 ==> 3

            jshell> System.out.println($1)
            3

            jshell> var num = $1
            num ==> 3

            jshell> /exit
            |  Goodbye
            $
          

Convenience Factory Methods for Collections


            $ jshell
            |  Welcome to JShell -- Version 11.0.8
            |  For an introduction type: /help intro

            jshell> Set.of("a", "b", "c")
            $1 ==> [a, b, c]

            jshell> $1.getClass()
            $2 ==> class java.util.ImmutableCollections$SetN

            jshell> List.of("a", "b", "c")
            $3 ==> [a, b, c]

            jshell> $3.getClass()
            $4 ==> class java.util.ImmutableCollections$ListN

            jshell> Map.ofEntries(
               ...> Map.entry("key1", new Object()),
               ...> Map.entry("key2", new Object())
               ...> )
            $5 ==> {key2=java.lang.Object@335eadca, key1=java.lang.Object@210366b4}

            jshell> $5.getClass()
            $6 ==> class java.util.ImmutableCollections$MapN
          

Erweiterung Optional


            package java9;

            import java.util.Optional;
            import java.util.stream.Stream;

            public class Optional9 {

              public <T> Stream<T> process(Optional<T> valueOpt) {
                T a = valueOpt.or(
                    () -> null
                ).get();

                valueOpt.ifPresentOrElse(t -> {
                  System.out.println("not empty");
                }, () -> {
                  System.out.println("empty");
                });

                return valueOpt.stream();
              }
            }
          

Private Methoden in Interfaces


            package java9;

            public interface PrivatMethod {

              default void defaultMethod() {
                System.out.println("Call defaultMethod");
                privateMethod();
              }

              private void privateMethod() {
                System.out.println("Call privateMethod");
                privateStaticMethod();
              }

              private static void privateStaticMethod() {
                System.out.println("Call privateStaticMethod");
              }
            }
          

Die privaten Methoden können außerhalb des Interfaces nicht aufgerufen werden

Process API


            $ jshell
            |  Welcome to JShell -- Version 11.0.8
            |  For an introduction type: /help intro

            jshell> var ph = ProcessHandle.current()
            ph ==> 48332

            jshell> ph.pid()
            $2 ==> 48332

            jshell> ph.parent()
            $3 ==> Optional[54948]

            jshell> ph.children()
            $4 ==> java.util.stream.ReferencePipeline$2@185d8b6

            jshell> var pi = ph.info()
            pi ==> [user: Optional[frank], cmd: /usr/lib/jvm/adoptop ... alTime: Optional[PT0.27S]]

            jshell> pi.user()
            $6 ==> Optional[frank]

            jshell> pi.commandLine()
            $7 ==> Optional[/usr/lib/jvm/adoptopenjdk-11-hotspot-amd64/bin/java -agentlib:jdwp=transport=dt_socket,address=localhost:41721 jdk.jshell.execution.RemoteExecutionControl 43829]

            jshell> pi.command()
            $8 ==> Optional[/usr/lib/jvm/adoptopenjdk-11-hotspot-amd64/bin/java]
          

Flow API

Die API basiert auf der Reactive-Stream Initiative


            package java9;

            import java.util.List;
            import java.util.concurrent.CountDownLatch;
            import java.util.concurrent.Flow;
            import java.util.concurrent.Flow.Subscription;
            import java.util.concurrent.SubmissionPublisher;

            public class Flows implements Flow.Subscriber<String> {

              private Subscription subscription;

              @Override
              public void onSubscribe(Subscription subscription) {
                this.subscription = subscription;
                System.out.println("Starting ...");
                this.subscription.request(1);
              }

              @Override
              public void onNext(String item) {
                System.out.println(item);
                this.subscription.request(1);
              }

              @Override
              public void onError(Throwable throwable) {
                throwable.printStackTrace();
              }

              static CountDownLatch countDown = new CountDownLatch(1);

              @Override
              public void onComplete() {
                System.out.println("Finished");
                countDown.countDown();
              }

              public static void main(String[] args) throws InterruptedException {
                SubmissionPublisher<String> publisher = new SubmissionPublisher<>();
                publisher.subscribe(new Flows());

                List.of("a", "b", "c", "d").forEach(publisher::submit);
                publisher.close();

                countDown.await();
              }
            }
          

Stream API


            $ jshell
            |  Welcome to JShell -- Version 11.0.8
            |  For an introduction type: /help intro

            jshell> Stream.of(10, 42, 4711)
            $1 ==> java.util.stream.ReferencePipeline$Head@548e7350

            jshell> $1.dropWhile(i -> i < 50).forEach(System.out::println)
            4711

            jshell> Stream.of(10, 42, 4711)
            $3 ==> java.util.stream.ReferencePipeline$Head@5a8806ef

            jshell> $3.takeWhile(i -> i < 50).forEach(System.out::println)
            10
            42

            jshell> IntStream.iterate(1, i -> i < 4711, i -> i*42).forEach(System.out::println)
            1
            42
            1764

            jshell> Stream.ofNullable(null)
            $5 ==> java.util.stream.ReferencePipeline$Head@7f13d6e

            jshell> $5.forEach(System.out::println)

            jshell> Stream.ofNullable("Frank")
            $7 ==> java.util.stream.ReferencePipeline$Head@10bbd20a

            jshell> $7.forEach(System.out::println)
            Frank
          

Java 10

Informationen

Release im März 2018

Support Ende im September 2018

https://openjdk.java.net/projects/jdk/10

Die wichtigsten Änderungen

  • Application Class-Data Sharing
  • Local-Variable Type Inference
  • Erweiterung Optional
  • ...

Local-Variable Type Inference


            package java10;

            import java.util.ArrayList;

            public class LocalVariable {

              public long process() {
                var list = new ArrayList<String>();
                list.add("Frank");

                var stream = list.stream();
                return stream.count();
              }
            }
          

Erweiterung Optional


            $ jshell
            |  Welcome to JShell -- Version 11.0.8
            |  For an introduction type: /help intro

            jshell> Optional.empty().orElseThrow()
            |  Exception java.util.NoSuchElementException: No value present
            |        at Optional.orElseThrow (Optional.java:382)
            |        at (#1:1)

            jshell> Optional.of(true).orElseThrow()
            $2 ==> true
          

Java 11

Informationen

Release im September 2018

Ist eine LTS-Version

Support Ende im September 2022

https://openjdk.java.net/projects/jdk/11

Die wichtigsten Änderungen

  • Entfernen von JAX-WS, SAAJ, JAXB, JAF, JTA,
    CORBA und der Common Annotations
  • API Erweiterungen
  • HTTP Client
  • Local-Variable Syntax für Lambda Parameters
  • Shebang Dateien
  • Sourcecode Dateien ausführen
  • ...

Entfernen von Java EE Modulen

JAX-WS (javax.xml.ws)

jakarta.xml.ws : jakarta.xml.ws-api : 2.3.3
com.sun.xml.ws : jaxws-rt : 2.3.3

SAAJ (javax.xml.soap)

jakarta.xml.soap : jakarta.xml.soap-api : 1.4.2
com.sun.xml.messaging.saaj : saaj-impl : 1.5.2

JAXB (javax.xml.bind)

jakarta.xml.bind : jakarta.xml.bind-api : 2.3.3
org.glassfish.jaxb : jaxb-runtime : 2.3.3

Entfernen von Java EE Modulen

JAF (javax.activation)

jakarta.activation : jakarta.activation-api : 1.2.2

JTA (javax.transaction)

jakarta.transaction : jakarta.transaction-api : 1.3.3

JPA (javax.persistence)

jakarta.persistence : jakarta.persistence-api : 2.2.3

Entfernen von Java EE Modulen

Validation (javax.validation)

jakarta.validation : jakarta.validation-api : 2.0.2

Common Annotations (javax.annotation)

jakarta.annotation : jakarta.annotation-api : 1.3.5

Expression Language (javax.el)

org.glassfish : jakarta.el : 3.0.3

Entfernen von Java EE Modulen

MAIL (javax.mail)

jakarta.mail : jakarta.mail-api : 1.6.5

JMS (javax.jms)

jakarta.jms : jakarta.jms-api : 2.0.3

CORBA (javax.rmi.CORBA)

Z. B. Eclipse GlassFisch oder WildFly

API Erweiterungen (String)


            $ jshell
            |  Welcome to JShell -- Version 11.0.8
            |  For an introduction type: /help intro

            jshell> "hello".isBlank()
            $1 ==> false

            jshell> "  ".isBlank()
            $2 ==> true

            jshell> " Hello World ".strip()
            $3 ==> "Hello World"

            jshell> " Hello World        ".strip()
            $4 ==> "Hello World"

            jshell> " Hello World        ".stripTrailing()
            $5 ==> " Hello World"

            jshell> " Hello World        ".stripLeading()
            $6 ==> "Hello World        "

            jshell> "         ".strip()
            $7 ==> ""

            jshell> "aaa\nbbb\nccc".lines().forEach(System.out::println)
            aaa
            bbb
            ccc

            jshell> "-".repeat(20)
            $8 ==> "--------------------"
          

API Erweiterungen (Character)


            $ jshell
            |  Welcome to JShell -- Version 11.0.8
            |  For an introduction type: /help intro

            jshell> Character.toString(100)
            $1 ==> "d"

            jshell> Character.toString(45)
            $2 ==> "-"
          

API Erweiterungen (Files)


            package java11;

            import java.io.IOException;
            import java.net.URI;
            import java.nio.file.Files;
            import java.nio.file.Path;
            import java.nio.file.Paths;
            import java.nio.file.StandardOpenOption;

            public class WriteString {
              public String process(URI uri) throws IOException {
                Path filePath = Paths.get(uri);

                Files.writeString(filePath, "Hello World",
                    StandardOpenOption.APPEND);

                return Files.readString(filePath);
              }
            }
          

HTTP Client


            package java11;

            import java.net.URI;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;
            import java.net.http.HttpResponse.BodyHandlers;
            import java.util.concurrent.CompletableFuture;

            public class HTTPClient {

              public CompletableFuture<String> process(String uri) {
                HttpClient client = HttpClient.newHttpClient();

                HttpRequest request = HttpRequest.newBuilder()
                  .uri(URI.create(uri)).build();

                return client.sendAsync(request,
                    BodyHandlers.ofString())
                  .thenApply(HttpResponse::body);
              }
            }
          

Local-Variable Syntax


            package java11;

            import java.util.function.BiConsumer;

            public class LocalVariable {

              public BiConsumer<String, String> process() {
                return (var x, var y) -> x.startsWith(y);
              }

            }
          

Shebang Dateien

Inhalt der Datei hw:


            #!/usr/bin/java --source 11

            public class HelloWorld {
              public static void main (String... args) {
                System.out.println("Hello World");
              }
            }
          

Ausgabe:

$ ./hw
Hello World
$

Sourcecode Dateien ausführen


            public class HelloWorld {
              public static void main(String[] args) {
                System.out.println("Hello World");
              }
            }
          

Ausgabe:

$ java HelloWorld.java
Hello World
$

Java 12

Informationen

Release im März 2019

Support Ende im September 2019

https://openjdk.java.net/projects/jdk/12

Die wichtigsten Änderungen

  • Unicode 11 (Japanese New Era)
  • ...

Java 13

Informationen

Release im September 2019

Support Ende im März 2020

https://openjdk.java.net/projects/jdk/13

Die wichtigsten Änderungen

  • Application Class Data Sharing
  • Unicode 12.1
  • ...

Java 14

Informationen

Release im März 2020

Support Ende im September 2020

https://openjdk.java.net/projects/jdk/14

Die wichtigsten Änderungen

  • Mehr Informationen bei NullPointerException
  • Switch Expressions
  • ...

Switch Expressions


            package java14;

            import java.time.DayOfWeek;

            public class SwitchExpressions {

              public int process(DayOfWeek day) {
                return switch (day) {
                  case MONDAY, FRIDAY, SUNDAY -> 6;
                  case TUESDAY -> 7;
                  case THURSDAY, SATURDAY -> 8;
                  default -> {
                    yield f();
                  }
                };
              }

              private int f() {
                return 4711;
              }
            }
          

Java 15

Informationen

Release im September 2020

Support Ende im März 2021

https://openjdk.java.net/projects/jdk/15

Die wichtigsten Änderungen

  • Edwards-Curve-Algorithmus für digitale
    Signaturen (EdDSA)
  • Entfernen der Nashorn JavaScript Engine
  • Text Blocks
  • ...

Text Blocks


            package java15;

            public class TextBlocks {

              private String html = """
                                    <html>
                                      <body>
                                        <p>Hello world!</p>
                                      </body>
                                    </html>
                                    """;

              private String sql = """
                                   SELECT *
                                   FROM PERSON p
                                   WHERE p.CITY = 'Köln'
                                   """;
            }
          

Java 16

Informationen

Release im März 2021

Support Ende im September 2021

https://openjdk.java.net/projects/jdk/16

Die wichtigsten Änderungen

  • Records
  • Pattern matching für instanceof
  • OpenJDK wurde nach GitHub umgezogen
  • Alpine Linux wird unterstützt

Records


            package java16;

            public class Records {

              public record Data(String a, Integer b) {}

              public static void main(String[] args) {
                Data data = new Data("Test", 5711);

                System.out.println(data.a());
                System.out.println(data.b());
                System.out.println(data.toString());
                System.out.println(data.hashCode());
                System.out.println(data.equals(data));
              }
            }
          

Pattern matching für instanceof


            package java16;

            public class PatternMatching {

              public void process(Object obj) {
                if(obj instanceof String s && s.isBlank()) {
                  System.out.println("obj is Blank String:" + s);
                }
              }

            }
          

Java 17

Informationen

Release im September 2021

Ist eine LTS-Version

Support Ende im September 2030

https://openjdk.java.net/projects/jdk/17

Mögliche Änderungen

  • Erweiterung der PRNG (RandomGenerator)

Vielen Dank für Ihre Aufmerksamkeit!

Lizenzen

Creative Commons Lizenzvertrag (CC BY-ND 4.0)

Dieses Werk ist unter der Creative-Commons-Lizenz vom Typ Namensnennung - Keine Bearbeitungen 4.0 International lizenziert.

Um eine Kopie dieser Lizenz einzusehen, besuchen Sie https://creativecommons.org/licenses/by-nd/4.0/deed.de oder schreiben Sie einen Brief an Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.

Backlog