JavaRush /Java-Blog /Random-DE /Java 11 veröffentlicht: neue Features und Fähigkeiten

Java 11 veröffentlicht: neue Features und Fähigkeiten

Veröffentlicht in der Gruppe Random-DE
Bisher erschienen neue Java-Versionen selten und mit Verzögerungen. Jetzt hält Oracle erfolgreich seinen selbst festgelegten Rhythmus von „neuem Java alle sechs Monate“ aufrecht. So haben wir vor ein paar Tagen, genau im Zeitplan, endlich Java SE 11 und die Implementierung des JDK (Java Development Kit) erhalten . Java 11 veröffentlicht: neue Features und Fähigkeiten – 1Wie immer wird die neue Version mit den alten kompatibel sein und die Unterstützung für Java 11 endet frühestens im Dezember 2026.

Neue Funktionen in Java SE 11 (sichtbar für Entwickler)

Denken Sie daran, dass in Java Änderungen durch die Implementierung des JEP „JDK Enhancement Proposal“ vorgenommen werden. JEP ist ein Vorschlag zur Verbesserung von OpenJDK und kann genehmigt, verzögert oder abgelehnt werden. Das heißt, im Wesentlichen ist eine Sammlung von JEPs eine Entwicklungsstrategie für OpenJDK. In eckigen Klammern vor dem neuen „Feature“ geben wir die Nummer des entsprechenden JEP an. [323] Syntax lokaler Variablen für Lambda-Parameter – var-Syntax für Lambda-Parameter Java 10 führte das Schlüsselwort var ein, das es ermöglichte, den Typ einer lokalen Variablen nicht explizit anzugeben. Dadurch wurde der Code vereinfacht. JEP 323 erweitert die Verwendung dieser Syntax um Lambda-Ausdrücke. Einfaches Beispiel:
list.stream ()
                 .map ((var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
Wie Simon Ritter , ein bekannter Java-Evangelist, schreibt, wird ein erfahrener Java-Programmierer feststellen, dass die Verwendung von var in diesem Fall möglicherweise unnötig ist, da der obige Code durch Folgendes ersetzt werden kann:
list.stream ()
                  .map (s -> s.toLowerCase ())
                  .collect (Collectors.toList ());
Warum dann var unterstützen? Es gibt nur einen Sonderfall: Wenn Sie einem Lambda-Parameter eine Anmerkung hinzufügen möchten. Dies ist nicht möglich, ohne dass ein Typ beteiligt ist. Um die Verwendung eines expliziten Typs zu vermeiden, können wir alles mit var wie folgt vereinfachen:
list.stream ()
                 .map ((@ Notnull var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
[330] Einzeldatei-Quellcode-Programme starten Verbesserung des Java-Launchers, um ein Programm als einzelne Datei mit Java-Quellcode zu starten. Java wird oft wegen seiner ausführlichen Syntax und der mehrstufigen „Zeremonie“ beim Starten selbst einer trivialen Anwendung kritisiert. Manchmal schreckt das Neulinge ab. So schreiben Sie eine Anwendung, die einfach „ Hallo Welt! “ ausgibt. ", müssen Sie eine Klasse mit einer öffentlichen statischen voidHauptmethode schreiben und die verwenden System.out.println. Anschließend müssen Sie den Code mit javac kompilieren . Danach können Sie schließlich die Anwendung starten, die die unglückliche Begrüßung anzeigt (natürlich führt die integrierte Entwicklungsumgebung, sowohl IDEA als auch die in JavaRush integrierte , diese „App-Startmagie“ von selbst aus – Anmerkung des Herausgebers ). Seien wir ehrlich: In den meisten Programmiersprachen sieht das eigentliche Skript zum Ausführen von Programmen viel einfacher aus. JEP 330 macht das Kompilieren einer Einzeldateianwendung überflüssig. Wenn Sie also jetzt die Befehlszeile verwenden, geben Sie einfach Folgendes ein
java HelloWorld.java
Der Java-Launcher erkennt, dass die Datei Java-Quellcode enthält, und kompiliert den Code in eine Klassendatei, bevor er ihn ausführt. Sie können Parameter nach oder vor dem Namen der Quellcodedatei platzieren. Die nach dem Namen platzierten Parameter werden bei der Ausführung der Anwendung als Parameter übergeben. Die vor dem Namen platzierten Parameter werden nach der Kompilierung des Codes als Parameter an den Java-Launcher übergeben. Compilerspezifische Optionen (z. B. Klassenpfad) werden zur Kompilierung auch an javac übergeben . Beispiel. Linie:
java -classpath / home / foo / java Hello.java Bonjour
entspricht diesen Zeilen:
javac -classpath / home / foo / java Hello.java
java -classpath / home / foo / java Hello Bonjour
[321] HTTP-Client (Standard) – Die HTTP-Client-API-Unterstützung wurde standardisiert. JDK 9 führte eine neue API zur Unterstützung des HTTP-Client-Protokolls (JEP 110) ein . Da JDK 9 auch das Java Platform Module System (JPMS) einführte , wurde diese API als Inkubatormodul eingebunden (das sind Module, um Entwicklern neue APIs zur Verfügung zu stellen, die in Java SE noch nicht zum Standard geworden sind, während die „Live“-APIs noch in der Entwicklung sind). zum Entfernen vorbereitet – Entwickler können neue APIs ausprobieren und versuchen, Feedback zu geben). Sobald die notwendigen Änderungen vorgenommen wurden (diese API wurde in JDK 10 aktualisiert), kann die API Teil des Standards werden. Daher ist die HTTP-Client-API jetzt offiziell in Java SE 11 enthalten . Dies führt ein neues Modul und Paket für das JDK ein, java.net.http . Die wichtigsten neuen Typen sind: HttpClient HttpRequest HttpResponse WebSocket Diese API kann synchron oder asynchron verwendet werden. Im asynchronen Modus werden CompletionFuturesund verwendet CompletionStages. [320] Entfernen der Java EE- und CORBA-Module Mit der Einführung des Java Platform Module System (JPMS) in der neunten Version von Java wurde es möglich, die monolithische rt.jar- Datei in mehrere Module aufzuteilen . Darüber hinaus können Sie mit JPMS eine Java-Laufzeitumgebung erstellen, die nur die von Ihrer Anwendung benötigten Module enthält und so deren Größe erheblich reduziert. Mit transparent definierten Modulgrenzen ist es viel einfacher, veraltete Teile der Java-API zu entfernen – genau das macht JEP 320. Das Metamodul java.se.ee umfasst sechs Module, die nicht Teil des Java SE 11-Standards sind und nicht enthalten sein werden im JDK:
  • Korba
  • Transaktion
  • Aktivierung
  • xml.bind
  • xml.ws
  • xml.ws.annotation
Diese Module waren in JDK 9 veraltet und wurden nicht standardmäßig in die Kompilierung oder Ausführung einbezogen. Dies bedeutet, dass der Versuch, eine Anwendung zu kompilieren oder auszuführen, die die APIs dieser Module unter JDK 9 oder JDK 10 verwendet, fehlgeschlagen ist. Wenn Sie die APIs dieser Module in Ihrem Code verwenden, müssen Sie sie als separates Modul oder Bibliothek bereitstellen.

Neue APIs

Dank der Aufnahme der Module HTTP Client und Flight Recorder in den Sprachstandard erschien eine große Anzahl neuer APIs in JDK 11 . Eine vollständige Liste der APIs finden Sie im folgenden umfassenden Vergleich verschiedener Versionen des JDK , zusammengestellt von Gunnar Morling. Und in diesem Hinweis werden wir einige neue Methoden auflisten, die nicht in den Modulen java.net.http , jdk.jfr und java.security enthalten sind . java.lang.String Dies ist wohl eine der wichtigsten Änderungen an String in der JDK 11-API und es gibt mehrere nützliche neue Methoden.
  • boolean isBlank (): Gibt true zurück, wenn die Zeichenfolge leer ist oder nur Leerzeichen enthält, andernfalls false.

  • Stream lines(): Gibt einen aus dieser Zeichenfolge extrahierten Zeilenstrom zurück, getrennt durch Zeilenabschlusszeichen.

  • String repeat (int): Gibt eine Zeichenfolge zurück, deren Wert die Verkettung dieser Zeichenfolge ist, die int -mal wiederholt wird.

  • String strip (): Gibt eine Zeichenfolge zurück, bei der alle Leerzeichen vor oder nach dem ersten Nicht-Leerzeichen entfernt wurden.

  • String stripLeading (): Gibt eine Zeichenfolge zurück, bei der alle Leerzeichen bis zum ersten Nicht-Leerzeichen entfernt wurden.

  • String stripTrainling (): Gibt eine Zeichenfolge mit allen Leerzeichen zurück, die nach dem Entfernen des letzten Nicht-Leerzeichens auftreten.
strip()Die Methode hat bereits etwas Ähnliches getan trim (), aber mit Leerzeichen bedeuten diese Methoden etwas anderes. Dabei trim()werden nur Leerzeichen abgeschnitten, und strip()auch Sonderzeichen wie Tabulatoren. java.lang.StringBuffer java.lang.StringBuilder Beide Klassen enthalten eine neue Methode , die / compareTo ()akzeptiert und zurückgibt . Die lexikalische Vergleichsmethode ähnelt der neuen Methode . java.io.ByteArrayOutputStreamStringBufferStringBuilderintcompareTo() CharSequence
  • void writeBytes (byte []): schreibt alle Bytes des Parameters in den java.io.FileReader- Ausgabestream
Hier gibt es zwei neue Konstruktoren, mit denen Sie angeben können Charset. java.io.FileWriter Vier neue Konstruktoren, mit denen Sie t angeben können Charse. java.io.InputStream
  • io.InputStream nullInputStream (): gibt zurück InputStream, wodurch keine Bytes gelesen werden. Wie verwende ich diese Methode? Sie können es sich als etwas wie /dev/null vorstellen, um nicht benötigte Ausgaben wegzuwerfen oder Eingaben einzufügen, die immer null Bytes zurückgeben.
java.io.OutputStream
  • io.OutputStream nullOutputStream ()
java.io.Reader
  • io.Reader nullReader ()
java.io.Writer
  • io.Writer nullWriter ()
java.lang.Character
  • String toString (int): Dies ist eine Überladung einer vorhandenen Methode, verwendet jedoch int anstelle von char.
java.lang.CharSequence
  • int compare (CharSequence, CharSequence): vergleicht lexikographisch zwei Instanzen CharSequence. Gibt einen negativen Wert, Null oder einen positiven Wert zurück, wenn die erste Sequenz lexikographisch kleiner, gleich oder größer als die zweite ist.
java.lang.ref.Reference
    lang.Object clone (): Der Java-Evangelist Simon Ritter gibt zu, dass ihn diese Methode verwirrt. Die Klasse Referenceimplementiert keine Schnittstelle Cloneableund diese Methode löst immer eine Ausnahme aus CloneNotSupportedException. Der Experte geht jedoch davon aus, dass diese Methode in Zukunft für etwas nützlich sein wird.
java.lang.Runtime java.lang.System Hier gibt es keine neuen Methoden. Erwähnen wir nur, dass die Methode runFinalizersOnExit ()aus beiden Klassen entfernt wurde, was zu Kompatibilitätsproblemen führen kann. java.lang.Thread Keine zusätzlichen Methoden, wir erwähnen nur, dass destroy ()sie stop (Throwable)entfernt wurden. Allerdings stop ()ist weiterhin verfügbar, was keine Argumente akzeptiert. Bitte beachten Sie dies, da es zu Kompatibilitätsproblemen kommen kann. java.nio.ByteBuffer java.nio.CharBuffer java.nio.DoubleBuffer java.nio.FloatBuffer java.nio.LongBuffer java.nio.ShortBuffer In allen diesen Klassen haben die Sprachentwickler eine Methode hinzugefügt mismatch (), die den relativen Index der Klassen findet und zurückgibt erste Nichtübereinstimmung zwischen diesem Puffer und einem bestimmten Puffer. java.nio.channels.SelectionKey
  • int interestOpsAnd (int)

  • int interestOpsOr (int)
java.nio.channels.Selector
  • int select (java.util.function.Consumer, long): Wählt eine Aktion auf Tasten aus und führt sie aus, deren entsprechende Kanäle für E/A-Vorgänge bereit sind. Der lange Parameter ist ein Timeout.

  • int select (java.util.function.Consumer): Funktioniert wie die obige Methode, jedoch ohne Zeitüberschreitung.

  • int selectNow (java.util.function.Consumer): Funktioniert wie die obige Methode, nur dass sie nicht blockiert.

java.nio.file.Files
  • String readString (Path): Liest den gesamten Inhalt einer Datei in eine Zeichenfolge und dekodiert Bytes mithilfe der UTF-8- Kodierung in Zeichen .

  • String readString (Path, Charset): Funktioniert wie die obige Methode, dekodiert jedoch Bytes mithilfe von in Zeichen Charset.

  • Path writeString (Path, CharSequence, java.nio.file. OpenOption []): Wenn Sie eine Zeichenfolge CharSequencein eine Datei schreiben, werden diese Zeichen in Bytes codiert (unter Verwendung von UTF-8 ).

  • Path writeString (Path, CharSequence, java.nio.file. Charset, OpenOption []): Funktioniert wie die obige Methode, nur werden die Zeichen mithilfe von in Bytes kodiert Charset.
java.nio.file.Path
  • Path(String, String[]): Gibt den Pfad zurück und transformiert einen Pfadstring oder eine Folge von Strings, die zusammen einen Pfadstring bilden.

  • Pfad (net.URI): Gibt den Pfad durch Transformation des URI zurück.
java.util.Collection
  • Object [] toArray (java.util.function.IntFunction): Gibt ein Array zurück, das alle Elemente in dieser Sammlung enthält, und verwendet die bereitgestellte Generatorfunktion, um das zurückgegebene Array zu verteilen.
java.util.concurrent.PriorityBlockingQueue java.util.PriorityQueue
  • void forEach (java.util.function.Consumer): Führt die angegebene Aktion für jedes iterierbare Element aus , bis alle Elemente verarbeitet wurden oder die Aktion eine Ausnahme auslöst.

  • boolean removeAll (java.util.Collection): Entfernt alle Elemente dieser Sammlung, die auch in der angegebenen Sammlung enthalten sind (optionaler Vorgang).

  • boolean removeIf (java.util.function.Predicate): Entfernt alle Elemente dieser Sammlung, die das angegebene Prädikat erfüllen.

  • boolean retainAll (java.util.Collection): Behält nur die Elemente in dieser Sammlung bei, die in der angegebenen Sammlung enthalten sind (optionaler Vorgang).
java.util.concurrent.TimeUnit
  • long convert (java.time.Duration): Konvertiert die angegebene Zeitdauer in diese Einheit.
java.util.function.Predicate
  • Predicate not(Predicate): Gibt ein Prädikat zurück, das die Negation des angegebenen Prädikats ist.
Zum Beispiel der folgende Code:
lines.stream ()

.filter (s ->! s.isBlank ())
lässt sich so umwandeln:
lines.stream ()

.filter (Predicate.not (String :: ISBLANK))
und wenn wir den statischen Import verwenden, erhalten wir Folgendes:
lines.stream ()
.filter (not(String :: ISBLANK))
java.util.Optional java.util.OptionalInt java.util.OptionalDouble java.util.OptionalLong
  • boolean isEmpty (): Gibt true zurück , wenn kein Wert vorhanden ist , andernfalls false .
java.util.regex.Pattern
  • Predicate asMatchPredicate (): Der Java-Experte Simon Ritter glaubt, dass sich hier möglicherweise ein echtes JDK-11-API-Juwel verbirgt. Diese Methode erstellt ein Prädikat, das prüft, ob dieses Muster mit einer bestimmten Eingabezeichenfolge übereinstimmt.
java.util.zip.Deflater
  • int deflate (ByteBuffer): Komprimiert die Eingabedaten und füllt den angegebenen Puffer mit komprimierten Daten.

  • int deflate (ByteBuffer, int): Komprimiert die Eingabedaten und füllt den angegebenen Puffer mit komprimierten Daten. Gibt die tatsächliche Menge der komprimierten Daten zurück.

  • void setDictionary (ByteBuffer): Legt fest, dass das angegebene Wörterbuch im angegebenen Puffer in Bytes komprimiert wird. Dies ist eine Überladung einer vorhandenen Methode, die jetzt ein ByteBufferArray anstelle eines Byte-Arrays akzeptieren kann.

  • void setInput (ByteBuffer): Legt die zu komprimierenden Eingabedaten fest. Es ist auch eine Überladung einer vorhandenen Methode.
java.util.zip.Inflater
  • int inflate (ByteBuffer): Entpackt Bytes in den angegebenen Puffer. Gibt die tatsächliche Anzahl unkomprimierter Bytes zurück.

  • void setDictionary (ByteBuffer): Setzt das angegebene Wörterbuch auf die Bytes im angegebenen Puffer. Ist eine überladene Form einer vorhandenen Methode.

  • void setInput (ByteBuffer): Legt die Eingabedaten für die Dekomprimierung fest. Eine überladene Form einer vorhandenen Methode.
javax.print.attribute.standard.DialogOwner Dies ist eine neue Klasse in JDK 11 und eine Attributklasse, die zur Unterstützung von Druck- oder Anpassungsseitenanforderungen verwendet wird, die über allen Fenstern oder einem bestimmten Fenster angezeigt werden sollen. javax.swing.DefaultComboBoxModel javax.swing.DefaultListModel
  • void addAll (Collection): Fügt alle in der Sammlung vorhandenen Elemente hinzu.

  • void addAll (int, Collection): Fügt alle in der Sammlung vorhandenen Elemente hinzu, beginnend beim angegebenen Index.
javax.swing.ListSelectionModel
  • int [] getSelectedIndices (): Gibt ein Array aller ausgewählten Indizes im ausgewählten Modell in aufsteigender Reihenfolge zurück.

  • int getSelectedItemsCount (): Gibt die Anzahl der ausgewählten Elemente zurück.
jdk.jshell.EvalException
  • shell.JShellException getCause (): Gibt den auslösbaren Grund im Ausführungsclient zurück, der von dieser EvalException präsentiert wird, oder null, wenn der Grund nicht existiert oder unbekannt ist.

Nicht-Entwicklerfunktionen von Java 11

[181] Nest-basierte Zugriffskontrolle Java und andere Sprachen unterstützen verschachtelte Klassen durch innere Klassen. Damit dies funktioniert, muss der Compiler bestimmte Tricks ausführen. Zum Beispiel:
public class Outer {
    private int outerInt;

     class Inner {
       public void printOuterInt() {
         System.out.println("Outer int = " + outerInt);
       }
     }
   }
Der Compiler ändert dies, um vor dem Kompilieren etwa Folgendes zu erzeugen:
public class Outer {
      private int outerInt;

      public int access$000() {
        return outerInt;
      }

    }


    class Inner$Outer {

      Outer outer;

      public void printOuterInt() {
        System.out.println("Outer int = " + outer.access$000());
      }
    }
Obwohl die innere Klasse logischerweise Teil desselben Codes wie die äußere Klasse ist, wird sie als separate Klasse kompiliert. Daher erfordert dieser Vorgang eine synthetische Join-Methode, die vom Compiler erstellt werden muss, um Zugriff auf das private Feld der äußeren Klasse zu ermöglichen. In diesem JEP wird das Konzept von Nestern vorgestellt, bei dem zwei Mitglieder desselben Nestes (in unserem Beispiel das äußere und das innere) Nestpartner sind. Für das Klassendateiformat werden zwei neue Attribute definiert: NestHost und NestMembers . Diese Änderungen sind für andere Sprachen nützlich, die verschachtelte Klassen und Bytecode unterstützen. Diese Funktion führt drei neue Methoden für java.lang.Class ein : Klasse getNestHost () Klasse [] getNestMembers () boolean isNestmateOf (Klasse) [309] Dynamische Klassendateikonstanten Dieses JEP beschreibt eine Erweiterung des Klassendateiformats zur Unterstützung des neuen Persistenter Pool von CONSTANT_Dynamic. Die Idee einer dynamischen Konstante scheint ein Oxymoron zu sein, aber im Wesentlichen kann man sie sich als Endwert in Java 11 vorstellen. Der Wert einer Pooling-Konstante wird nicht zur Kompilierungszeit festgelegt (im Gegensatz zu anderen Konstanten), sondern verwendet einen Bootstrap Methode zur Bestimmung des Wertes zum Zeitpunkt der Durchlaufzeit. Daher ist der Wert dynamisch, aber da sein Wert nur einmal festgelegt wird, ist er auch konstant. Diese Funktion richtet sich in erster Linie an Personen, die neue Sprachen und Compiler entwickeln, die Bytecodes und Klassendateien als Ausgabe zur Ausführung auf der JVM generieren. [315] Aarch64-Intrinsics verbessern Dieses JEP wurde von der Red Hat-Community vorgeschlagen. Die JVM kann jetzt speziellere Anweisungen verwenden, die im Arm 64-Befehlssatz verfügbar sind. Dies verbessert insbesondere die Leistung der Methoden, sin ()und cos ()der log ()Klasse java.lang.Math . [318] Epsilon: Ein No-Op-Garbage Collector Wie bei JEP 315 können Sie Red Hat für die Einführung des Epsilon Garbage Collectors danken. Epsilon ist insofern ungewöhnlich, als es eigentlich keinen Müll sammelt! Beim Erstellen neuer Objekte wird bei Bedarf Speicher zugewiesen, der von nicht registrierten Objekten belegte Speicherplatz wird jedoch nicht zurückgefordert. " Was ist der Punkt? ", - du fragst. Es stellt sich heraus, dass diese „Müllsammlung“ zwei Verwendungszwecke hat:
  1. Dieser Garbage Collector soll zunächst sicherstellen, dass neue GC-Algorithmen hinsichtlich ihrer Auswirkungen auf die Leistung bewertet werden. Die Idee besteht darin, eine Beispielanwendung mit Epsilon auszuführen und eine Reihe von Metriken zu generieren. Der neue Garbage-Collection-Algorithmus wird aktiviert, die gleichen Tests werden ausgeführt und anschließend werden die Ergebnisse verglichen.

  2. Für sehr kurze Aufgaben (denken Sie an serverlose Funktionen in der Cloud), bei denen Sie garantieren können, dass Sie den dem Heap zugewiesenen Speicher nicht überschreiten. Dies kann die Leistung verbessern, indem der Overhead (einschließlich der Erfassung von Statistiken, die für die Entscheidung, ob der Collector ausgeführt werden soll) im Anwendungscode entfällt. Wenn der Heap-Speicherplatz erschöpft ist, kann die JVM auf eine von drei Arten falsch konfiguriert sein:
    • Normal heißt OutOfMemoryError.
    • Führen Sie einen Heap-Reset durch
    • Die JVM-Festplatte ist ausgefallen und führt möglicherweise eine andere Aufgabe aus (z. B. das Starten eines Debuggers).
[328]: Flight Recorder Flight Recorder ist ein Low-Level-Datenerfassungsframework für die JVM. Vor JDK 11 war dies eine kommerzielle Funktion in der Oracle JDK-Binärdatei. Oracle beseitigt jetzt die funktionalen Unterschiede zwischen dem Oracle JDK und einem Build von OpenJDK. Das macht Flight Recorder :
  • Stellt eine API zum Erzeugen und Konsumieren von Daten als Ereignisse bereit
  • Bietet einen Puffermechanismus und ein binäres Datenformat
  • Ermöglicht die Anpassung und Filterung von Ereignissen
  • Stellen Sie Ereignisse für Betriebssystem-, JVM-HotSpot- und JDK-Bibliotheken bereit
Hier gibt es zwei neue Module: jdk.jfr und jdk.management.jfr . [329] ChaCha20- und Poly1305-Kryptografiealgorithmen In diesem JEP geht es um die Aktualisierung der vom JDK verwendeten Chiffren . In diesem Fall werden die Verschlüsselungsalgorithmen ChaCha20 und ChaCha20-Poly1305 gemäß RFC 7539 implementiert. ChaCha20 ist eine relativ neue Stream-Verschlüsselung, die die ältere, unsichere RC4- Verschlüsselung ersetzen kann . [333] ZGC: Ein skalierbarer Garbage Collector mit geringer Latenz Ein experimenteller skalierbarer Garbage Collector mit geringer Latenz. Konzipiert für die Verwendung mit Anwendungen, die einen großen Heap (Multigigabyte) und eine geringe Latenz erfordern. Es verwendet einen Single-Generation-Heap und erledigt die meisten (aber nicht alle) Garbage-Collection-Aufgaben gleichzeitig mit der Anwendung. [332] Transport Layer Security (TLS) 1.3 TLS 1.3 (RFC 8446) ist ein wichtiger Patch für das TLS-Transportschicht-Sicherheitsprotokoll, der im Vergleich zu früheren Versionen erhebliche Sicherheits- und Leistungsverbesserungen bietet. Das JDK unterstützt jetzt diese Protokollversion. Das Material basiert auf einem Artikel von Simon Ritter und offizieller Dokumentation .
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION