Java 14 Funktionen

Im Einklang mit der Tradition des sechsmonatigen Zyklus wird nach der Veröffentlichung von Java 13 am 17. September 2019 Java 14, eine weitere nicht-LTS-Version, am 17. März 2020 veröffentlicht.

Java 14 Funktionen

Hier ist die Liste der Funktionen von Java 14:

  • Switch-Ausdrücke (Standard) – JEP 361
  • Pattern Matching für instanceof (Vorschau) – JEP 305
  • Hilfreiche NullPointerExceptions – JEP 358
  • Records (Vorschau) – JEP 359
  • Textblöcke (Zweite Vorschau) – JEP 368
  • Verpackungswerkzeug (Inkubator) – JEP 343
  • NUMA-bewusste Speicherzuweisung für G1 – JEP 345
  • JFR-Ereignis-Streaming – JEP 349
  • Nicht-flüchtige zugeordnete Byte-Puffer – JEP 352
  • ZGC auf macOS – JEP 364
  • ZGC auf Windows – JEP 365
  • API für den Zugriff auf fremden Speicher (Inkubator) – JEP 370

Java 14 Installationseinrichtung auf Mac OS

  • Um mit Java 14 zu beginnen, laden Sie das JDK von hier herunter.
  • Kopieren und entpacken Sie dann die Tar-Datei im Verzeichnis /Library/Java/JavaVirtualMachines, wie unten gezeigt:
$ cd /Library/Java/JavaVirtualMachines

$ sudo cp ~/Downloads/openjdk-14_osx-x64_bin.tar.gz /Library/Java/JavaVirtualMachines

$ sudo tar xzf openjdk-14_osx-x64_bin.tar.gz

$ sudo rm openjdk-14_osx-x64_bin.tar.gz

Sobald das erledigt ist, öffnen Sie die Datei bash_profile mit einem beliebigen Texteditor. Ich verwende vim ~/.bash_profile. Legen Sie den Pfad von Java 14 als JAVA_HOME fest, speichern Sie die Änderungen und führen Sie source ~/.bash_profile aus, um die Änderungen zu reflektieren.

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home

Schließlich sind Sie bereit, Programme mit Java 14 zu kompilieren und auszuführen. Wir werden JShell verwenden, ein interaktives REPL-Befehlszeilentool zum schnellen Testen der neuen Java-14-Funktionen.

Es ist wichtig zu beachten, dass viele Funktionen, die in Java 14 veröffentlicht wurden, in der Vorschau sind. Das bedeutet, dass sie zwar voll funktionsfähig sind, aber in Zukunft geändert werden können. Einige könnten in den nächsten Versionszyklen als Standard festgelegt oder einfach entfernt werden. Um Vorschau-Funktionen zu testen, müssen Sie beim Ausführen von JShell oder Java-Programmen explizit --enable-preview setzen, wie unten gezeigt:

jshell --enable-preview

javac --release 14 --enable-preview Author.java

In den nächsten Abschnitten werden wir einige der Sprach- und JVM-Funktionen diskutieren.

Empfohlene Lektüre: Java 14 unter Linux installieren

1. Switch-Ausdrücke

Schalterausdrücke, die in den letzten beiden Versionen – Java 12 und Java 13 – als Vorschau-Features verfügbar waren, haben in Java 14 endlich den permanenten Status erreicht.

  • Java 12 führte die Lambda-Syntax für Schalterausdrücke ein, wodurch mehrere Fallbezeichnungen für die Mustererkennung ermöglicht wurden und Verzweigungen vermieden wurden, die zu umständlichem Code führten. Es wurde auch eine vollständige Fallabdeckung erzwungen, bei der ein Kompilierungsfehler ausgelöst wurde, wenn nicht alle Eingabefälle abgedeckt waren.
  • Java 13, die zweite Vorschauversion, führte yield-Anweisungen anstelle von break ein, um Werte aus einem Ausdruck zurückzugeben.

Java 14 hat diese Funktionen nun endgültig standardmäßig gemacht.

String result = switch (day) {
            case "M", "W", "F" -> "MWF";
            case "T", "TH", "S" -> "TTS";
            default -> {
                if(day.isEmpty())
                    yield "Please insert a valid day.";
                else
                    yield "Looks like a Sunday.";
            }

        };
System.out.println(result);
Java 14 Switch Expressions

Hinweis: Yield ist kein neues Schlüsselwort in Java. Es wird nur in Schalterausdrücken verwendet.

2. Musterabgleich für instanceof (Vorschau)

Wenn Sie jeden Java-Entwickler bitten, ihren Code zu zeigen, werden Sie eine häufige Verwendung von instanceof-Bedingungen im gesamten Code finden. Normalerweise wird nach einer instanceof-Bedingung eine Typumwandlung durchgeführt.

Java 14 vereinfacht diese Umständlichkeit, indem die bedingte Extraktion viel prägnanter wird.

Vor Java 14:

if (obj instanceof Journaldev) {
  Journaldev jd = (Journaldev) obj;
  System.out.println(jd.getAuthor());
}

Ab Java 14:

if (obj instanceof Journaldev jd) {
  System.out.println(jd.getAuthor());
}

Im obigen Code wird die Instanz jd nur zugewiesen, wenn obj vom Typ Journaldev ist. Der Gültigkeitsbereich der Variablen ist auf den bedingten Block beschränkt.

3. Hilfreiche NullPointerExceptions

Null Pointer Exceptions sind ein Albtraum für jeden Entwickler. Früher, bis Java 13, war es schwierig, die berüchtigten NPEs zu debuggen. Entwickler mussten auf andere Debugging-Tools zurückgreifen oder manuell die Variable/Methode ermitteln, die null war, da der Stack-Trace nur die Zeilennummer anzeigen würde.

Vor Java 14:

String name = jd.getBlog().getAuthor()

//Stacktrace
Exception in thread "main" java.lang.NullPointerException
    at NullPointerExample.main(NullPointerExample.java:5)

Java 14 führte ein neues JVM-Feature ein, das bessere Einblicke mit einem detaillierteren Stack wie unten gezeigt bietet:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Blog.getAuthor()" because the return value of "Journaldev.getBlog()" is null
    at NullPointerExample.main(NullPointerExample.java:4)

Hinweis: Das obige Feature ist kein Sprachfeature. Es handelt sich um eine Verbesserung in der Laufzeitumgebung.

4. Records (Vorschau)

A record is a data class that stores pure data. The idea behind introducing records is to quickly create simple and concise classes devoid of boilerplate code.

Normalerweise würde eine Klasse in Java erfordern, dass Sie equals(), hashCode(), die Getter- und Setter-Methoden implementieren. Obwohl einige IDEs die automatische Generierung solcher Klassen unterstützen, ist der Code immer noch umständlich. Mit einem record müssen Sie einfach eine Klasse wie folgt definieren.

record Author(){}
//oder
record Author (String name, String topic) {}

Der Java-Compiler generiert automatisch einen Konstruktor, private finale Felder, Zugriffsmethoden, equals/hashCode und toString Methoden. Die automatisch generierten Getter-Methoden der obigen Klasse sind name() und topic().

Um den generierten Code zu überprüfen, verwenden Sie javap Author nach dem Kompilieren des Programms mit javac. Die folgende Abbildung zeigt die generierte Klasse für record Author (String name, String topic) {}:

Javap Records Java 14

Die Semantik von Records ist ähnlich wie bei Data Classes in Kotlin

Darüber hinaus können wir dem Record auf folgende Weise zusätzliche Felder, Methoden und Konstruktoren hinzufügen:

record Author (int id, String name, String topic) {
    static int followers;

    public static String followerCount() {
        return "Followers are "+ followers;
    }

    public String description(){
        return "Author "+ name + " writes on "+ topic;
    }

    public Author{
    if (id < 0) {
        throw new IllegalArgumentException( "id must be greater than 0.");
     }
   }
}

Der im Record definierte zusätzliche Konstruktor wird als Compact-Konstruktor bezeichnet. Er besteht aus keinen Parametern und ist lediglich eine Erweiterung des kanonischen Konstruktors.

A compact constructor wouldn’t be generated as a separate constructor by the compiler. Instead, it is used for validation cases and would be invoked at the start of the main constructor.

Einige wichtige Dinge, die bei Records zu beachten sind:

  • A record can neither extend a class nor it can be extended by another class. It’s a final class.
  • Records können nicht abstrakt sein
  • Records können keine andere Klasse erweitern und keine Instanzfelder im Body definieren. Instanzfelder müssen ausschließlich in der Zustandsbeschreibung definiert werden
  • Erklärte Felder sind privat und final
  • Der Body eines Records ermöglicht statische Felder und Methoden

Empfohlene Lektüre: Java Records

4.1) Werte in Referenzfeldern eines Datensatzes können mutiert werden

Es ist wichtig zu beachten, dass für Felder, die Objekte darstellen, nur die Referenz unveränderlich ist. Die zugrunde liegenden Werte können verändert werden. Die folgende Illustration zeigt einen Datensatz, in dem die ArrayList verändert wird. Wie Sie sehen können, wird der Wert immer dann geändert, wenn die ArrayList verändert wird.

Java 14 Records Mutable Values For References

4.2) Datensätze können Schnittstellen implementieren

Der folgende Code zeigt ein Beispiel für die Implementierung einer Schnittstelle mit Datensätzen:

record Author(String name, String topic) implements Information {
  public String getFullName() {
    return "Author "+ name + " writes on " + topic;
  }
}

interface Information {
  String getFullName();
}

Hier ist die Ausgabe des obigen Codes in Aktion in einem JShell:

Java 14 Records With Interface

4.3) Datensätze unterstützen mehrere Konstruktoren

Datensätze ermöglichen die Deklaration mehrerer Konstruktoren mit oder ohne Parameter, wie unten gezeigt:

record Author(String name, String topic) {
  public Author() {

    this("NA", "NA");
  }

  public Author(String name) {

    this(name, "NA");
  }
}

4.4) Records Allow Modifying Accessor Methods

Obwohl Records öffentliche Zugriffsmethoden für die in der Zustandsbeschreibung definierten Felder generieren, ermöglichen sie auch die Neudefinition der Zugriffsmethoden im Rumpf, wie unten gezeigt:

record Author(String name, String topic) {
  public String name() {
        return "This article was written by " + this.name;
    }
}

4.5) Überprüfen Sie Record und seine Komponenten zur Laufzeit

Records stellen uns isRecord() und getRecordComponents() zur Verfügung, um zu überprüfen, ob die Klasse ein Record ist, und auch einen Blick auf seine Felder und Typen zu werfen. Die folgende Abbildung zeigt, wie es gemacht wird:

Java 14 Records Runtime Check

Auch wenn wir in den obigen Codebeispielen zusätzliche Felder und Methoden zum Record hinzugefügt haben, stellen Sie sicher, dass Sie es nicht übertreiben. Records sind als einfache Datenträger konzipiert, und wenn Sie viele zusätzliche Methoden implementieren möchten, ist es besser, auf die normale Klasse zurückzugreifen.

5. Textblöcke (Vorschau)

Textblöcke wurden als Vorschau-Funktion in Java 13 eingeführt, um das einfache Erstellen von mehrzeiligen Zeichenkettenliterale zu ermöglichen. Es ist nützlich, um problemlos HTML-, JSON- oder SQL-Abfragezeichenketten zu erstellen.

In Java 14 sind Textblöcke weiterhin in der Vorschau mit einigen neuen Ergänzungen. Wir können jetzt verwenden:

  • Backslash, um schön aussehende mehrzeilige Zeichenkettenblöcke anzuzeigen.
  • \s wird verwendet, um abschließende Leerzeichen zu berücksichtigen, die standardmäßig vom Compiler ignoriert werden. Es behält alle vor ihm vorhandenen Leerzeichen bei.
String text = """
                Did you know \
                Java 14 \
                has the most features among\
                all non-LTS versions so far\
                """;

String text2 = """
                line1
                line2 \s
                line3
                """;


String text3 = "line1\nline2 \nline3\n"

//text2 und text3 sind gleich.

Referenzen: OpenJDK 14

Source:
https://www.digitalocean.com/community/tutorials/java-14-features