Wir haben uns bereits daran gewöhnt, dass alle sechs Monate ein neues JDK-Release erscheint. Bisher hat sich dieser Ansatz bewährt und die Sorge mancher Entwickler, mit den Updates nicht hinterherzukommen, war umsonst: Es gibt nur wenige Halbjahresänderungen und sie sind nicht mehr so global wie zuvor. Nun, unerfahrene Programmierer bemerken die Innovation möglicherweise überhaupt nicht. Für zukünftige Softwareentwickler ist es jedoch besser, über Innovationen auf dem Laufenden zu bleiben. In diesem Artikel werden wir traditionell akzeptierte Erweiterungsvorschläge (JEPs) beschreiben. Java 13 enthält nur fünf JEPs und 76 neue Kernbibliothekselemente (von denen fast die Hälfte einfache Ergänzungen zum java.io-Paket sind).
JEP 355 : Textblöcke (Vorschau)
Beginnen wir mit der Änderung der Syntax der Sprache. Die bedeutendsten davon sind Textblöcke. Sie ermöglichen es Ihnen, Escape-Zeichen zu vermeiden und wissen, wie Zeichenfolgen formatiert werden. Sie erinnern sich vielleicht , dass JDK 12 nicht die erwartete Funktion „Raw String Literals“ (JEP 326) für die Arbeit mit String-Literalen enthielt. In Java 13 wurde es durch JEP 355 mit seinen Textblöcken ersetzt. Sie erinnern sich wahrscheinlich daran, dass in Java eine Zeichenfolge in doppelte Anführungszeichen gesetzt wird. Das ist gut, aber das Problem besteht darin, dass eine Zeile nicht mehr als eine Zeile der Quelldatei belegen kann (um Verwechslungen mit einer Java-Zeile zu vermeiden, nennen wir hier eine Dateizeile „Zeile“). Nun, lassen Sie uns herumgehen und beispielsweise das Symbol verwenden,\n
wenn ein Umbruch erforderlich ist, oder die Verkettung mehrzeiliger Ausdrücke. Es wird nicht sehr schön! Besonders umständlich sind Textliterale mit eingebetteten HTML-, XML-, SQL- oder JSON-Fragmenten. All diese Escapezeichen, Verkettungen und manuellen Bearbeitungen machen den Code unpraktisch zu schreiben und schwer zu lesen. Textblöcke versuchen, dieses Problem zu lösen. Sie beginnen äh... mit dreifachen doppelten Anführungszeichen und enden damit (ich weiß, das hört sich nicht sehr gut an). Alles zwischen den Anführungszeichen wird als Teil der Zeile interpretiert, einschließlich Zeilenumbrüchen. Textblöcke können genauso verwendet werden wie Standardtextliterale, und Java kompiliert den Code auf die gleiche Weise. Auf öffnende Anführungszeichen muss ein Zeilentrennzeichen folgen. Textblöcke können nicht in einer Zeile verwendet werden, daher der Code
String smallBlock = """Only one line""";
führt zu folgenden Fehlern:
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
String smallBlock = """Text Block""";
^
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
String smallBlock = """Text Block""";
^
Ein einfaches HTML-Fragment kann nun wie folgt geschrieben werden:
String htmlBlock = """
<html>
<body>
<p>CodeGym Web page</p>
</body>
<html>
""";
Lassen Sie uns einige Feinheiten erwähnen, die Sie bei der Verwendung von Textblöcken besser beachten sollten. Die Platzierung der schließenden Anführungszeichen erweist sich als wichtig: Sie bestimmt, wie mit gelegentlichen Leerzeichen umgegangen wird. Im obigen Beispiel sind die schließenden Anführungszeichen an der Einrückung des HTML-Textes ausgerichtet. In diesem Fall entfernt der Compiler die Einrückungsräume und als Ergebnis erhalten wir eine Zeile wie diese:
<html>
<body>
<p>My web page</p>
</body>
</html>
Beachten Sie:Eine solche Zeile enthält am Ende der Zeile einen Zeilenumbruch. Wenn es nicht benötigt wird, können schließende Anführungszeichen „““ direkt nach dem </html>-Tag platziert werden. Wenn wir die schließenden Anführungszeichen näher an den linken Rand verschieben, ändert sich die Menge der entfernten Einzüge. Wenn wir sie um zwei Leerzeichen nach links verschieben würden, würden wir jeder Zeilenzeile zwei Leerzeichen zum Einrücken hinzufügen. Wenn Sie zum linken Rand wechseln, bleibt die gesamte Polsterung erhalten. Das Verschieben der Anführungszeichen weiter nach rechts hat keine Auswirkung und fügt keine weitere Einrückung hinzu. Textblöcke wurden in JDK 13 als Vorschaufunktion integriert. Das bedeutet, dass sie noch nicht in der entsprechenden Java-Sprachspezifikation enthalten sind. Das heißt, es ist nicht klar, ob dieses Feature ein fester Bestandteil der Sprache wird oder ob es hier nur ein Gast ist. Derzeit können Entwickler die Funktion testen und ihre Meinung dazu abgeben. Das Schicksal von Textblöcken wird davon abhängen: Die Funktion kann verbessert werden, und wenn sie Ihnen nicht gefällt, kann sie ganz entfernt werden. Wenn Sie Textblöcke in der Praxis ausprobieren möchten, denken Sie daran, dass Vorschaufunktionen explizit einbezogen werden müssen, damit sie kompiliert und ausgeführt werden können. Zusammenstellung:
javac --enable-preview --release 13 TextBlock.java
Um die Anwendung auszuführen, müssen Sie die Vorschaufunktionen aktivieren:
java --enable-preview TextBlock
Die Klasse String
verfügt über drei neue Methoden, die diese Sprachänderung ergänzen:
formatted()
: Formatieren Sie eine Zeichenfolge, indem Sie die Zeichenfolge selbst als Formatzeichenfolge verwenden. Äquivalent zu einer Herausforderungformat(this, args)
stripIndent()
: Entfernt zufällige Leerzeichen aus einer Zeichenfolge. Dies ist nützlich, wenn Sie mehrzeilige Zeichenfolgen lesen und denselben Leerraumausschluss anwenden möchten wie bei einer expliziten Deklaration.translateEscapes()
: Gibt eine Zeichenfolge mit Escape-Sequenzen (z. B.\ r
) zurück, übersetzt in den entsprechenden Unicode-Wert.
@PreviewFeature
würde die Einführung einer Anmerkung in solchen Situationen helfen, aber sie ist noch nicht im JDK enthalten (obwohl sie mit hoher Wahrscheinlichkeit in JDK 14 erscheinen wird).
JEP 354 : Ausdruck wechseln (Vorschau)
Mit Java 12 wurde ein Vorschlag für eine neue Form des Schreibens von Ausdrücken mit einer Switch-Anweisung eingeführt – JEP 325 . Es stellte sich heraus, dass es sich um die allererste Vorschaufunktion handelte, und ihr Schicksal beweist, dass es eine großartige Idee ist, den Benutzern Vorschläge zu unterbreiten. Vor JDK 12switch
konnte es nur als Anweisung verwendet werden, die eine Aktion ausführt, aber kein Ergebnis zurückgibt. Aber in Java 12 erlaubte es die Verwendung switch
als Ausdruck, der ein Ergebnis zurückgibt, das einer Variablen zugewiesen werden kann. Es gab weitere Änderungen an der Syntax von case-Anweisungen innerhalb von switch
. Schauen wir uns ein Beispiel von JEP an, um zu verstehen, wie das funktioniert.
int numberOfLetters;
switch(dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
numberOfLetter = 6;
break;
case TUESDAY
numberOfLetter = 7;
break;
case THURSDAY
case SATURDAY
numberOfLetter = 8;
break;
case WEDNESDAY
numberOfLetter = 9;
break;
default:
throw new IllegalStateException("Huh?: " + day);
}
In diesem Beispiel verwenden wir value, dayOfWeek
um den Wert zuzuweisen numberOfLetters
. Aufgrund der Besonderheiten der Arbeit des Bedieners switch
ist dieser Code nicht der schönste und es kann leicht zu Fehlern kommen. Erstens: Wenn wir vergessen, auf jede Gruppe von Fallbeschriftungen eine Anweisung anzuwenden break
, greifen wir standardmäßig auf die nächste Gruppe von Fallbeschriftungen zurück. Dies kann zu Fehlern führen, die schwer zu finden sind. Zweitens müssen wir jede Gruppe von Fallbezeichnungen definieren. Wenn wir es vergessen, erhalten wir natürlich einen Compilerfehler, diese Option ist jedoch nicht ideal. Unser Code ist außerdem recht ausführlich, da jeder Wert dayOfWeek
eine eigene Groß-/Kleinschreibung haben muss. Mit der neuen Syntax erhalten wir viel saubereren und weniger fehleranfälligen Code:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
default -> throw new IllegalStateException("Huh?: " + day);
};
Jetzt müssen wir die Zuweisung nur einmal vornehmen (aus dem Rückgabewert des Ausdrucks switch
) und können eine durch Kommas getrennte Liste für die Fallbezeichnungen verwenden. Und da wir den Operator nicht verwenden break
, beseitigen wir die damit verbundenen Probleme. Die Ausdruckssyntax switch
ermöglicht es uns, eine ältere Syntax zu verwenden, sodass wir sie in JDK 12 wie folgt schreiben können:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
break 6;
case TUESDAY
break 7;
case THURSDAY
case SATURDAY
break 8;
case WEDNESDAY
break 9;
default:
throw new IllegalStateException("Huh?: " + day);
};
Laut der Java-Community break
kann die Verwendung von Überladung zur Angabe eines Rückgabewerts verwirrend sein. break
In der Java-Sprache können Sie auch (und continue
) mit einer Bezeichnung wie dem bedingungslosen Sprungoperator verwenden goto
. JEP 354 hat diese Verwendung geändert break
, daher ändert sich unser Code in Java 13 leicht:
int numberOfLetters = switch (dayOfWeek) {
case MONDAY:
case FRIDAY:
case SUNDAY:
yield 6;
case TUESDAY
yield 7;
case THURSDAY
case SATURDAY
yield 8;
case WEDNESDAY
yield 9;
default:
throw new IllegalStateException("Huh?: " + day);
};
Die nächsten drei JEPs sind mit der Java Virtual Machine verknüpft.
JEP 350 Dynamisches CDS-Archiv
Mit dieser Erweiterung können Sie Klassen am Ende der Ausführung einer Java-Anwendung dynamisch archivieren. Mit CDS oder Class Data Sharing können Sie alle beim Start gestarteten Klassen in ein spezielles Archiv packenclass data sharing
und dabei standardmäßig die Liste dieser Klassen verwenden. Dies führt zu einer erheblichen Beschleunigung beim Starten von Anwendungen und zur Einsparung von RAM. Bisher war die Verwendung von AppCDS ein mehrstufiger Prozess, bei dem eine Liste relevanter Klassen erstellt und anhand dieser Liste ein Archiv erstellt wurde, das für nachfolgende Läufe verwendet wurde. Jetzt ist nur noch ein einmaliger Start der Anwendung erforderlich, wobei das Flag -XX: ArchiveClassesAtExit
den Speicherort angibt, in den das Archiv geschrieben werden soll. Bei diesem Ansatz werden Klassen automatisch in ein Archiv gepackt, nachdem die Anwendung normal beendet wurde.
JEP 351 ZGC : Nicht verwendeten Speicher freigeben
Vor einem Jahr führte JDK 11 ZGC ein, einen experimentellen, skalierbaren Garbage Collector mit geringer Latenz. Zunächst verhielt sich ZGC recht seltsam: Es erlaubte nicht, Speicher an das Betriebssystem zurückzugeben, selbst wenn dieser nicht mehr benötigt wurde. In einigen Umgebungen wie Containern, in denen Ressourcen von mehreren Diensten gleichzeitig genutzt werden, kann dies die Skalierbarkeit und Effizienz des Systems einschränken. Der ZGC-Heap besteht aus sogenannten ZPages. Wenn ZPages während des Garbage-Collection-Zyklus gelöscht werden, werden sie an den ZPageCache zurückgegeben. Die ZPages in diesem Cache sind danach sortiert, wie kürzlich sie verwendet wurden. In Java 13 gibt ZGC Seiten, die als längere Zeit nicht genutzt identifiziert wurden, an das Betriebssystem zurück. Dadurch können sie für andere Prozesse wiederverwendet werden.JEP 353 Reimplementieren Sie die alte Socket-API
Beide API-Implementierungenjava.net.Socket
sind java.net.ServerSocket
immer noch JDK 1.0. In diesem und allen nachfolgenden JDKs verwendet die Implementierung dieser APIs mehrere Techniken (z. B. die Verwendung des Thread-Stacks als I/O-Puffer), die sie unflexibel und schwer zu warten machen. Um dieses Problem zu lösen, wurde in JDK 13 eine neue Implementierung bereitgestellt NioSocketImpl
. Es ist kein nativer Code mehr erforderlich, was die Portierung auf verschiedene Plattformen erleichtert. Diese Klasse verwendet außerdem den vorhandenen Puffer-Cache-Mechanismus (und vermeidet die Verwendung des Thread-Stacks für diesen Zweck) und sperrt java.util.concurrent
statt synchronisierter Methoden. Dies vereinfacht die Integration mit Fasern von Project Loom .
Neue APIs
Wir haben bereits erwähnt, dass Java 13 76 neue APIs in den Basisklassenbibliotheken enthält. Sie decken folgende Bereiche ab:- Aktualisierungen der Unicode-Unterstützung.
- Drei neue Methoden
String
zur Unterstützung von Textblöcken (siehe Beschreibung zu JEP 255 oben). - Klassen
java.nio
haben jetzt absolute (im Gegensatz zu relativen)get
undMethoden festlegen. Sie enthalten wie die abstrakte Basisklasse Buffer
eine Methodeslice()
zum Abrufen eines Teils des Puffers. - Die Klassenmethode erzwingt
force()
,MappedByteBuffer
dass ein Pufferabschnitt in seinen Sicherungsspeicher geschrieben wird. nio.FileSystem
fügt drei neue überladene FormularenewFileSystem()
für den Zugriff auf den Inhalt einer Datei als Dateisystem hinzu.- Eine neue interessante Methode ist
javax.annotation.processing.ProcessingEnvironment
aufgetaucht.isPreviewEnabled()
. Hier erfahren Sie, ob die Vorschaufunktionen aktiviert sind. Dies ist interessant, da die oben erwähnte Anmerkung@PreviewFeature
erst mit der Veröffentlichung von JDK 14 verfügbar sein wird. DocumentBuilderFactory
undSAXParserFactory
erhalten Siejavax.xml.parsers
drei neue Methoden zum Erstellen von Namespace-fähigen Instanzen.
GO TO FULL VERSION