Was erwartet Sie 2020 von Java?

2020 ist bereits in vollem Gange. Lassen Sie uns diskutieren, welche Veränderungen in der Java-Welt uns in diesem Jahr erwarten. Dieser Artikel listet die wichtigsten Trends von Java und JDK auf. Und ich werde mit den Ergänzungen der Leser in den Kommentaren zufrieden sein.

Machen Sie sofort einen Vorbehalt, dass der Artikel eher ein Faktencharakter ist. Details zu jedem diskutierten Thema finden Sie auf der Website des entsprechenden Projekts oder in Veröffentlichungen in Open Source.

Bild

Also fangen wir an. Leider müssen Sie sofort diejenigen enttäuschen, die den Java-Release-Zyklus nicht zu sehr verfolgen, aber auf ein langes Support-Programm (LTS) warten. In diesem Jahr warten wir auf Veröffentlichungen mit nur einem kurzen Support-Lebenszyklus (STS).
Als erstes werden wir die bevorstehende Veröffentlichung von JDK 14 betrachten, die Mitte März veröffentlicht werden soll. In diesem Veröffentlichungszyklus werden bis zu 16 JEPs beansprucht. Hier ist die vollständige Liste:
305:Pattern Matching zum Beispiel (Vorschau)
343:Verpackungswerkzeug (Inkubator)
345:NUMA-Aware Memory Allocation für G1
349:JFR-Ereignis-Streaming
352:Nichtflüchtige zugeordnete Bytepuffer
358:Hilfreiche NullPointerExceptions
359:Aufzeichnungen (Vorschau)
361:Ausdrücke wechseln (Standard)
362:Veralten Sie die Solaris- und SPARC-Ports
363:Entfernen Sie den CMS-Garbage Collector (Concurrent Mark Sweep)
364:ZGC unter macOS
365:ZGC unter Windows
366:Verwerfen Sie die ParallelScavenge + SerialOld GC-Kombination
367:Entfernen Sie die Pack200-Tools und die API
368:Textblöcke (Zweite Vorschau)
370:Foreign-Memory Access API (Inkubator)

Viele JEPs aus dieser Liste wurden auf der Joker 2019-Konferenz ausführlich behandelt. Ich werde mich auf diejenigen konzentrieren, die mir am interessantesten erscheinen.

Pattern Matching zum Beispiel (Vorschau)


Der lange JEP erscheint endlich in der Vorschau. Ich denke, wenn Sie ein praktizierender Programmierer sind, der seit vielen Jahren Java-Code schreibt, dann sind Sie mehr als einmal auf diesen Schmerz gestoßen:

if (obj instanceof String) {
    String s = (String) obj;
    System.out.println(s.toUpperCase());
}

Wenn Sie Code auch in Kotlin geschrieben haben oder schreiben, ist der Schmerz beim Anzeigen des Java-Codes etwas schlimmer. Die Teilnehmer des Amber-Projekts werden uns ihre Vision von Pattern Matching in Java vorstellen, die diesen Schmerz lindern soll. Mit dem Aufkommen von Java 14 können wir das Beispiel wie folgt umschreiben:

if (obj instanceof String s) {
   System.out.println(s.toUpperCase());
}

Es scheint, dass das Add-On nicht so wertvoll ist - wir speichern eine Codezeile. Angenommen, wir möchten Folgendes tun:

if (obj instanceof String) {
    String s = (String) obj;
    if (s.contains(“prefix_”)) {
       return s.toUpperCase();
    }
}
return null;

Es sieht sperrig aus, nicht wahr? Versuchen wir das Gleiche, aber mit Pattern Matching.

return (obj instanceof String s) && s.contains(“prefix_”) ? s.toUpperCase() : null;

Also wird es offensichtlich besser sein. Beachten Sie jedoch, dass der Status dieser Funktionalität Vorschau ist. Mal sehen, was sich im Laufe der Zeit ändert. Für mich wird es definitiv mein Leben verbessern.

Hilfreiche NullPointerExceptions


2020 ist auf dem Hof, und Sie schreiben immer noch, damit NullPointerExceptions für Sie herausfliegen? Mach dir keine Sorgen, du bist wahrscheinlich nicht der einzige. Goetz Lindenmaier und Ralf Schmelter schlugen keinen neuen Weg vor, um von NullPointerExceptions wegzukommen (Optional ist noch bei uns), aber sie schlugen vor, den Debugging-Prozess der Anwendung zu verbessern, um genau zu verstehen, wo Null liegt. Stellen wir uns also vor, wir schreiben den Code um fünf Uhr ... natürlich nachts. Und wir haben diese Funktion geschrieben:

public String getStreetFromRequest(Request request) {
   return request.getAddress().getStreet().toUpperCase();
}

Nicht schlecht, aber sie haben völlig vergessen, die Anmerkungen @Nullable und @Nonnull einzufügen und die Adresse in den übertragenen Feldern zu überprüfen. Ich habe eine NullPointerException erhalten. Was sagt uns die Ausnahme?

Exception in thread "main" java.lang.NullPointerException
	at Program.getStreetFromRequest(Program.java:10)
	at Program.main(Program.java:6)

Leider sehen wir nur eine Reihe, eine Klasse und einen Stapel. Wohin ist null genau zurückgekehrt? Vielleicht ist das eine Anfrage? Vielleicht hat getAddress () null zurückgegeben? Oder vielleicht getStreet ()? Nun, Anrufketten tun manchmal weh.

Die JEP-Autoren schlagen eine Lösung vor: Wenn eine Ausnahme ausgelöst wird, soll sie den Stapel umgehen, um festzustellen, wo genau null zurückgegeben wird, und dann den Namen der Variablen / Methoden anzeigen. Versuchen wir Java 14 mit der Option -XX: + ShowCodeDetailsInExceptionMessages. Wir fangen an und werden ein bisschen anders:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because the return value of "Address.getStreet()" is null
	at Program.getStreetFromRequest(Program.java:10)
	at Program.main(Program.java:6)

Jetzt wissen wir, dass Nachtprogrammierung nicht gut ist (aber manchmal dazu führt, dass Aufgaben pünktlich erledigt werden), und in unserem Programm haben wir vergessen, dass die Adresse kein Pflichtfeld ist.

Aufzeichnungen (Vorschau)


Immer noch Getter / Setter / Equals / HashCode mit Idee generieren? Dann kommt dieser JEP zu dir!
Datenklassen sind weit entfernt vom letzten Platz im Leben eines Entwicklers von Anwendungssoftware. Jedes Mal müssen wir entweder Methoden von Datenklassen mit unserer bevorzugten IDE generieren oder verschiedene Plugins zur Kompilierungszeit verwenden, um die erforderlichen Methoden wie lombok zu generieren.

Infolgedessen haben wir eine Menge ähnlichen Codes:

public class Request {
    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
       this.address = address;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Request request = (Request) o;
        return Objects.equals(address, request.address);
    }

    @Override
    public int hashCode() {
        return Objects.hash(address);
    }

    @Override
    public String toString() {
        return "Request{" +
                "address=" + address +
                '}';
    }
}

Oder so:
@Data
@AllArgsConstructor
public class Request {
    private Address address;
}

In Java 14 schlagen Mitglieder des Amber-Projekts eine neue Syntax zum Erstellen von Datenklassen vor. Verwenden Sie dazu den neuen Keyword-Datensatz. Die Syntax für Record unterscheidet sich geringfügig von der für Klassenbeschreibungen oder Aufzählungen und ist Kotlin geringfügig ähnlich. Der obige Code kann wie folgt umgeschrieben werden:

public record Request(Address address) {
}

Alle Datensatzfelder haben standardmäßig private und endgültige Modifikatoren. Der Datensatz selbst ist eine endgültige Klasse und kann nicht von einer anderen Klasse geerbt werden, kann jedoch Schnittstellen implementieren. In den Datensatzklassen aus der Box erhalten wir: getters-Methoden, einen öffentlichen Konstruktor, dessen Parameter alle Datensatzfelder in der Beschreibungsreihenfolge sind, equals / hashCode und toString. Aus dem Unangenehmen: Wir können dem Datensatz keine Felder hinzufügen, außer denen, die nach dem Klassennamen angegeben sind. Dieser Code führt beispielsweise zu einem Fehler:

public record Request(Address address) {
   private final String anotherParameter; // compilation error
}

Textblöcke (Zweite Vorschau)


Textblöcke wurden in Java 13 als Vorschau veröffentlicht. Wir Benutzer haben sie gedreht, gedreht und Feedback gegeben (ich bin der festen Überzeugung, dass Sie Java 13 bereits mit Vorschau verwenden). Infolgedessen haben die Java-Ersteller geringfügige Änderungen an Textblöcken vorgenommen. Zunächst können wir jetzt explizit angeben, wo die Zeile endet, indem wir Escape-Sequenzen in unsere Zeile einfügen. Hier ist ein Beispiel:

public static void main(String[] args) {
        final var test = """
                This is the long text block with escape string \s
                that is really well done            \s
                """;
        System.out.println(test);
}

Jetzt setzen wir explizit alle Leerzeichen auf das Zeichen \ s und alle Leerzeichen werden auf das Zeichen \ s gespeichert.

Zweitens können wir jetzt lange Zeilen eines Textblocks umbrechen, ohne in der letzten Zeile \ n Zeichen zu erhalten. Dazu müssen wir nur am Zeilenumbruch \ hinzufügen. Wie sieht es aus:

public static void main(String[] args) {
        final var test = """
                This is the long text block with escape string \
                that is really well-done functional            
                """;
System.out.println(test);

Nach der Ausführung erhalten wir die folgende Zeile: "Dies ist der lange Textblock mit Escape-Zeichenfolge, der wirklich gut funktioniert."

Eine gute Ergänzung, scheint mir. Ich freue mich sehr darauf, diese Funktionalität in Standard umzusetzen.
Alle Funktionen, die wir überprüft haben, werden wahrscheinlich auf bevorstehenden Konferenzen ausführlich diskutiert. Einige davon wurden bereits auf der Joker 2019 besprochen. Lesen Sie unbedingt den Joker 2019-Vortrag über „Feature Evolution in Java 13 und darüber hinaus“ von Cay Horstmann.

Und noch einige interessante Dinge.


Es gibt zwei interessante Punkte auf der JEP-Liste im Inkubator. Zunächst werden wir ein universelles Tool haben, mit dem Installationsprogramme für verschiedene Betriebssysteme erstellt werden können (zum Schluss möchte ich denjenigen sagen, die sich mit der Installation von Programmen unter Windows befasst haben). Jpacker kann msi / exe-Installationsprogramme für Windows, macOS-Pakete und rpm / deb für Linux erstellen. Mal sehen, was daraus wird, aber in den seltenen Fällen, in denen ich etwas für den Desktop getan habe, habe ich persönlich darunter gelitten, dass ich kein reguläres Tool zum Zusammenbauen des Installationsprogramms hatte.

Noch vielversprechender ist die neue API für den Zugriff auf "Foreign-Memory", d. H. jede Art von nativem oder beständigem Gedächtnis. Diese API ist in erster Linie für Java-Datenbankersteller oder Framework-Ersteller wie beispielsweise Netty nützlich. Mithilfe von Unsafe und ByteBuffer optimieren sie den Speicherzugriff so weit wie möglich außerhalb des Heapspeichers.

Nächste Version. Freude und Frustration


Im September warten wir auf eine weitere kurzfristige Support-Version unter Nummer 15. Die Liste der JEPs, die in der endgültigen Version enthalten sein werden, ist noch offen. Bisher können Sie viele verschiedene Änderungen in der Sprache selbst, in der Standardbibliothek und in der virtuellen Maschine feststellen.
Hier ist die Liste der Kandidaten (sie kann sich schnell ändern, siehe hier: bugs.openjdk.java.net/secure/Dashboard.jspa?selectPageId=19114 ):
111:Additional Unicode Constructs for Regular Expressions
116:Extended Validation SSL Certificates
134:Intuitive Semantics for Nested Reference Objects
152:Crypto Operations with Network HSMs
198:Light-Weight JSON API
218:Generics over Primitive Types
300:Augment Use-Site Variance with Declaration-Site Defaults
301:Enhanced Enums
302:Lambda Leftovers
303:Intrinsics for the LDC and INVOKEDYNAMIC Instructions
306:Restore Always-Strict Floating-Point Semantics
338:Vector API (Incubator)
339:Compiler Intrinsics for Java SE APIs
348:Compiler Intrinsics for Java SE APIs
356:Enhanced Pseudo-Random Number Generators
360:Sealed Types (Preview)
371:Hidden Classes

Wie Sie sehen können, hat die Liste noch nicht viel erwartet. Für mich ist es zunächst einmal Project Loom. Die Idee der strukturellen Parallelität war in den letzten Jahren sehr beliebt. Coroutinen können die Aufgabe des wettbewerbsfähigen parallelen Rechnens und der asynchronen Ausführung von Aufgaben erheblich vereinfachen. Gute Beispiele für die Umsetzung dieser Idee finden sich beispielsweise in den Sprachen Kotlin (Coroutinen) und Go (Goroutinen). Java untersucht auch die Idee der strukturellen Parallelität, und es gibt bereits erste Ergebnisse. Derzeit können Sie sie nur anzeigen, indem Sie das JDK aus dem Projekt-Repository kompilieren.

Ein vielversprechendes Projekt Valhalla hat uns auch noch nicht mit einer Vorschau zufrieden gestellt. Ein interessanter Bericht zu diesem Projekt wurde auf der Joker 2019 vorgestellt („Benötigt Java Inline-Typen? Eine enge Ansicht des Performance Engineers zum Valhalla-Projekt“ von Sergey Kuksenko).

Was ist in der Liste dargestellt?

Das erste, was auffällt, ist die JSON-API. Die Frage stellt sich sofort - warum? Es gibt eindeutig keine eindeutige Antwort. Im JEP-Abschnitt zur Motivation heißt es, dass JSON zu einem Standard für Webdienste geworden ist. Jetzt ist es an der Zeit, Java SE für die Interaktion mit JSON anzupassen (obwohl es derzeit eine Menge Bibliotheken zum Parsen von JSON gibt). Die wahrscheinlichste Erklärung ist die Möglichkeit für Softwareentwickler, eine kleine Kern-API zu verwenden, um die Größe des Bundles zu reduzieren, ohne den schweren Jackson auf sich ziehen zu müssen. Ich sehe keine andere Erklärung, da es nicht einmal eine Datenbindung geben wird.

Wir sehen auch eine Reihe von Verbesserungen im Zusammenhang mit der kryptografischen API. Zunächst möchten JDK-Entwickler den Prozess der Validierung von SSL-Zertifikaten erweitern, indem sie Unterstützung für EVSSL-Zertifikate hinzufügen. Mit dieser API in Java können Sie feststellen, ob eine SSL-Verbindung von einem EV-Zertifikat als vertrauenswürdig eingestuft wird (Extended Validation). Das EVSSL-Zertifikat gemäß der Richtlinie wird vollständig unterstützt. Ein neuer kryptografischer EdDSA-Algorithmus wird ebenfalls hinzugefügt und die Überprüfung der HSM-Kryptografie wird verbessert.

Aus sprachlichen Gründen würde ich die Implementierung von Generika auf Grundelementen herausgreifen. Jeder, der jemals in C # programmiert und auf Java umgestellt hat, könnte sich wahrscheinlich die Frage stellen, warum Sie keine generischen Typen für Grundelemente ausführen können. Die Antwort ist einfach: Generika arbeiten nur mit Objekten, und Grundelemente sind keine Objekte und erben insbesondere keine Objektklasse. Es ist nicht das erste Jahr, in dem ein Krieg zu diesem Thema geführt wurde, und Brian Goetz kehrt wieder darauf zurück. Bisher gibt es nichts Besonderes zu beschreiben. Die Aufgabe ist klar - Konstrukte wie List zu unterstützen. Aber auch im Moment gibt es 13 offene Fragen, die gelöst werden müssen, bevor diese Funktionalität implementiert wird. Ehrlich gesagt frage ich mich, wie diese Serie enden wird.

Und das Letzte, was ich ansprechen möchte, sind die versiegelten Typen. Dies ist der nächste Schritt zum Mustervergleich. Sealed Types ist eine Spracherweiterung, die den Sealed (Modifikator) implementiert und Schlüsselwörter für eine Klasse oder Schnittstelle zulässt.

Mit der versiegelten Klasse beschränken wir die Anzahl der Nachkommen auf nur die Klassen, die in Genehmigungen (eine explizite Einschränkung) oder in derselben Kompilierungseinheit (Datei) angegeben sind. Beispielbeschreibung einer versiegelten Klasse:

// 
public abstract sealed class Base {
   public static class ChildA extends Base{}
   public static class ChildB extends Base{}
}

// 
public sealed interface BaseInterface permits ChildC, ChildD{
}

//  
public class ChildC implements BaseInterface {
}
//  
public class ChildD implements BaseInterface {
}

Der versiegelte Modifikator stellt sicher, dass nur eine begrenzte Anzahl von Nachkommen die Basisklasse erweitern oder eine Schnittstelle implementieren kann. Diese Eigenschaft kann bei der Verarbeitung von Objekten dieser Klassen verwendet werden. Und natürlich ist dies ein großartiger Kandidat für die Verwendung in einer switch-Anweisung mit Mustervergleich.

Fazit


Wir haben uns die verschiedenen JDK-Innovationen in diesem Jahr angesehen. Einige von ihnen werden schießen, andere nicht. Vor allem aber erwarte ich in den neuen JDKs neue kleine (oder nicht so) Optimierungen, die unsere Programme mit jeder kostenlosen Version schneller machen. Und wenn Sie beim letzten Joker 2019 waren und den Bericht von Tagir Valeev Java 9-14: Kleine Optimierungen besucht haben, dann waren Sie höchstwahrscheinlich wie ich beeindruckt von der Arbeit, die Mitwirkende zur Optimierung von JDK leisten. Die Ergebnisse sind auf den ersten Blick nicht sichtbar und spiegeln sich nicht in mehr als einem JEP wider, aber wir verwenden sie jeden Tag.

Gute Java-Releases für uns alle. Entdecken Sie neue Plattformfunktionen, besuchen Sie Konferenzen und folgen Sie Trends.

All Articles