Résumé des nouvelles fonctionnalités de Java 14

Java 14 est sorti le 17 mars 2020. Java SE 14 Platform JSR 389

Télécharger

Vous pouvez le télécharger sur le site OpenJDK. https://jdk.java.net/14/

SDKMAN! est recommandé pour l'installation sur Mac et Linux

Outre Oracle Open JDK, il existe les distributions suivantes qui peuvent être utilisées gratuitement dans le commerce.

Puisqu'il ne s'agit pas de LTS, il ne semble pas être publié sur Amazon Corretto. La mise à jour sera publiée en avril avec 14.0.1 et en juillet avec 14.0.2.

Oracle JDK est disponible à des fins de développement, mais vous devez acheter un abonnement Java SE à des fins commerciales.

JEP De grands changements sont organisés dans JEP. https://openjdk.java.net/projects/jdk/14/

Cette fois, 16 JEP ont été importés. Beaucoup ont un impact important. 305: Pattern Matching for instanceof (Preview) 343: Packaging Tool (Incubator) 345: NUMA-Aware Memory Allocation for G1 349: JFR Event Streaming 352: Non-Volatile Mapped Byte Buffers 358: Helpful NullPointerExceptions 359: Records (Preview) 361: Switch Expressions (Standard) 362: Deprecate the Solaris and SPARC Ports 363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector 364: ZGC on macOS 365: ZGC on Windows 366: Deprecate the ParallelScavenge + SerialOld GC Combination 367: Remove the Pack200 Tools and API 368: Text Blocks (Second Preview) 370: Foreign-Memory Access API (Incubator)

Je vais résumer par domaine.

Spécifications linguistiques

Certains des changements liés aux spécifications linguistiques sont les suivants. 359: Records (Preview) 305: Pattern Matching for instanceof (Preview) 368: Text Blocks (Second Preview) 361: Switch Expressions (Standard)

359: Records (Preview)

L'enregistrement a été ajouté en tant que fonction de prévisualisation en tant que classe pour la conservation des données. Une version améliorée reflétant les commentaires dans Java 15 sera prévisualisée et formalisée dans Java 16.

Définissez-le comme enregistrement.

record Foo(int x, int y) {}

Les autres classes ne peuvent pas être héritées.

record Nom de l'enregistrement(Statut) {Définition}

Ce serait une classe comme celle-ci:

class Foo extends Record {
  //État défini comme final privé
  private final int x;
  private final int y;
  //Aucun champ d'instance supplémentaire ne peut être défini

  //Un constructeur qui définit l'état du champ est défini
  public Foo(int x, int y) {
    this.x = x;
    this.y = y;
  }

  //Une méthode portant le même nom que l'état est définie
  public int x() {
    return x;
  }
  public int y() {
    return y;
  }

  //Un hashCode qui reflète l'état est défini
  public int hashCode() { ... }
  //Les états égaux à comparer sont définis
  public boolean equals() { ... }
  //Un toString qui affiche l'état est défini
  public String toString() { ... }
}

La méthode d'obtention est définie, mais la méthode de définition de la valeur n'est pas définie. En d'autres termes, c'est un objet immuable. De plus, comme il n'est pas get / set, il n'est pas compatible avec Java Bean. Les méthodes hashCode () et ʻequals () `sont en fait invokeDynamic et le code d'implémentation est généré à l'exécution.

Vous pouvez définir un constructeur pour la vérification d'état et la normalisation comme suit:

record Range(int lo, int hi) {
  public Range {
    if (lo > hi) throw IllegalArgumentException();
    //Les champs qui n'ont pas été définis seront définis ultérieurement
  }
}

Vous ne pouvez pas définir d'enregistrement dans une classe interne non statique. La compilation de code comme celui-ci entraînera l'erreur «déclarations d'enregistrement non autorisées dans les classes internes».

public class NestedRecord {
  class Foo {
      record Bar(int x){}
  }
}

Vous pouvez compiler du code comme ceci:

public class NestedRecord {
  static class Foo {
      record Bar(int x){}
  }
}

Extension API

record est une classe qui hérite de java.lang.Record.

Si vous essayez d'écrire du code qui hérite de Record comme suit, vous obtiendrez l'erreur les enregistrements ne peuvent pas étendre directement java.lang.Record.

class Foo extends Record {
}

Les méthodes liées aux enregistrements ont été ajoutées à la classe Class. Vous pouvez déterminer si le type est record avec la méthode ʻisRecord. Vous pouvez également obtenir les composants définis par record avec getRecordComponents`. Cependant, il semble que la valeur puisse être obtenue via Field car elle ne peut pas être obtenue via RecordComponent.

jshell> Foo.class.isRecord()
$9 ==> true

jshell> Foo.class.getRecordComponents()
$10 ==> RecordComponent[2] { int x, int y }

jshell> String.class.isRecord()
$11 ==> false

jshell> String.class.getRecordComponents()
$12 ==> null

Limitation de «record» comme nom de type

Il est limité de donner le nom «enregistrement» à un type (comme un type d'enregistrement d'interface de classe). Une erreur se produira si --enable-preview est ajouté.

$ jshell --enable-preview
|Bienvenue dans JShell--Version 14-ea
|Pour un aperçu, tapez: /help intro

jshell> class record{}
|Erreur:
|ici'record'N'est pas autorisé
|À partir de la version 13'record'Est un nom de type restreint et ne peut pas être utilisé pour déclarer un type
|  class record{}
|        ^

jshell> String record=""
record ==> ""

jshell> record Rec(int record){}

jshell> Rec record=new Rec(3)
record ==> Rec[record=3]

Au fait, ce "à partir de la version 13" est faux, mais à partir de la 14. http://mail.openjdk.java.net/pipermail/amber-dev/2020-February/005623.html

Contrairement à enum, ce n'est pas un mot-clé, vous pouvez donc utiliser record pour les noms de variables, les champs et les noms de composants d'enregistrement. Si vous n'ajoutez pas --enable-preview, un avertissement sera affiché.

$ jshell
|Bienvenue dans JShell--Version 14-ea
|Pour un aperçu, tapez: /help intro

jshell> class record{}
|avertissement:
|  'record'Peut être un nom de type restreint dans une version future et ne peut pas être utilisé dans les déclarations de type ou comme type d'élément d'un tableau
|  class record{}
|        ^
|Créé le suivant:Record de classe

Amélioration future

Au départ, c'était le même JEP que les types scellés, mais il était séparé. Cette fonction vous permet de limiter l'héritage de classe à un nombre limité de classes. Il semble être en préversion dans Java 15. JEP 360: Sealed Types (Preview)

Des améliorations dans l'aperçu 2 sont suggérées ici. https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001913.html

--java.util.Record est une classe, mais la classe en ligne de Valhalla ne peut hériter que de l'interface, donc cela devrait-il être une interface?

référence Commentaires de Stephen Colebourne https://mail.openjdk.java.net/pipermail/amber-dev/2019-November/005271.html

305: Pattern Matching for instanceof (Preview)

C'est une correspondance de modèle. Tout d'abord, une correspondance de motif utilisant l'instance de sera incluse dans 14 en tant qu'aperçu. http://openjdk.java.net/jeps/305

Vous pouvez faire correspondre les valeurs avec la valeur instanceof pattern. Le modèle est une définition constante ou variable. Dans le cas d'une définition de variable, si les types correspondent, cela devient vrai et une valeur est affectée à cette variable.

if (x instanceof Integer i) {
    // can use i here
}

Ce serait bien s'il pouvait être utilisé avec un commutateur, mais il a été défini dans un autre JEP et transféré vers Java 15. JEP draft: Pattern matching for switch (Preview)

De plus, il semble que la fonction de décomposition de l'enregistrement (déconstruction) et son imbrication soient introduits et qu'il entrera Java 15 en tant qu'aperçu 2. http://openjdk.java.net/jeps/8235186

Comme horaire raisonnable

Qu'il sera

Cependant, 17LTS a une perspective d'inclure la fonction de correspondance de modèle comme fonction standard.

368: Text Blocks (Second Preview)

Vous pouvez définir une chaîne de caractères comprenant des sauts de ligne. Insérez dans "" "" `. Dans JDK13, il y a quelques changements tels que les sauts de ligne d'échappement dans ce qui a été inclus comme aperçu dans JDK13. Il sera standard dans JDK15.

// same as "You can write\ntwo line string.\n"
var str = """
  You can write
  two line string.
  """;

Le début "" "" "ne peut pas être suivi d'une chaîne, et le retrait est basé sur le" "" "ou la partie la moins profonde de la chaîne interne.

var str = """
..You can write
..two line string.
  """;
var str = """
..  You can write
..  two line string.
  """;

Vous pouvez également échapper aux sauts de ligne.

var str = """
  You can write \
  two line string, \
  but this is single.
  """;

Ce sera "" Vous pouvez écrire une chaîne de deux lignes, mais celle-ci est unique. "`.

L'espace à la fin de la ligne est supprimé. Donc, si vous avez besoin d'un espace à la fin de la ligne, mettez \ s pour indiquer que vous avez besoin d'un espace.

var str = """
  test\s
  test \s
  """;

Ce sera "" test_ \ ntest__ \ n "`. (Dans Qiita, même si vous mettez plusieurs espaces, ce sera un espace)

Vous ne pouvez pas incorporer de variables dans une chaîne. Au lieu de cela, la méthode formatted est fournie comme méthode d'instance, et vous pouvez maintenant écrire:

var str = """
Bonjour,%Mme.
Il fait beau aujourd'hui, n'est-ce pas.
  """.formatted("Kishida");

361: Switch Expressions (Standard)

Vous pouvez maintenant utiliser l'instruction précédente switch comme expression. Introduit en tant qu'aperçu dans Java 12, modifié dans Java 13 et officiellement introduit dans Java 14. https://openjdk.java.net/jeps/361

Switch était une instruction, mais comme de nombreux commutateurs l'utilisaient pour affecter des valeurs à la même variable ou renvoyer dans tous les cas, il peut également être utilisé comme une expression afin de pouvoir être écrit efficacement. Je vais.

En d'autres termes, comme ça.

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY -> 7;
    case THURSDAY, SATURDAY -> 8;
    case WEDNESDAY -> 9;
};

Vous pouvez également renvoyer une valeur avec yield.

int result = switch (s) {
    case "Foo":
        yield 1;
    case "Bar":
        yield 2;
    default:
        System.out.println("Neither Foo nor Bar, hmmm...");
        yield 3;
}

La forme de base consiste à renvoyer une valeur avec «yield».

case LABEL: yield expression;

Il semble que vous puissiez écrire comme lambda comme sucre de syntaxe.

case LABEL -> expression;

Il vous permet également de spécifier plusieurs valeurs pour «case».

switch (day) {
    case MONDAY, FRIDAY, SUNDAY: 
        numLetters = 6;
        break;
    ...
};

Ces extensions «case» sont également valides pour les instructions «switch» existantes.

JVM En tant que changement de comportement de JVM, il y a un message détaillé avec NullPointerException. 358: Helpful NullPointerExceptions

358: Helpful NullPointerExceptions

Je pense que les programmeurs Java adorent «NullPointerException». Cependant, je craignais que le message ne soit pas complet. Dans Java 14, vous pouvez maintenant afficher des messages détaillés sur NullPointerException.

Par exemple, si vous avez le code suivant:

public class Sample {
  static String s;
  public static void main(String... args) {
    s.length();
  }
}

Si vous l'exécutez normalement dans Java 14, vous ne verrez aucun message spécial comme dans les versions précédentes.

$ java Sample.java
Exception in thread "main" java.lang.NullPointerException
        at Sample.main(mysample.java:4)

Si vous l'exécutez avec l'option -XX: + ShowCodeDetailsInExceptionMessages, vous verrez ce que l'erreur s'est produite lorsque vous avez appelé quoi pour quoi.

$ java -XX:+ShowCodeDetailsInExceptionMessages Sample.java
Exception in thread "main" java.lang.NullPointerException:
    Cannot invoke "String.length()" because "Sample.s" is null
        at Sample.main(mysample.java:4)

Cette construction de message est effectuée lorsque le message est récupéré, il semble donc avoir peu d'impact sur les performances.

Pour JShell, ajoutez -R-XX: + ShowCodeDetailsInExceptionMessages.

$ jshell -R-XX:+ShowCodeDetailsInExceptionMessages
|Bienvenue dans JShell--Version 14-ea
|Pour un aperçu, tapez: /help intro

jshell> String[] strs = {null}
strs ==> String[1] { null }

jshell> strs[0].toUpperCase()
|Exception java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because "REPL.$JShell$11.strs[0]" is null
|        at (#2:1)

API Les modifications de l'API sont les trois JEP suivants. 349: JFR Event Streaming 370: Foreign-Memory Access API (Incubator) 352: Non-Volatile Mapped Byte Buffers En plus de cela, il y avait l'ajout de la prise en charge des formes plurielles dans CompactNumberFormat et une méthode pratique dans StrictMath. De plus, l'API relative à l'outil de packaging, qui sera abordée plus loin dans la section Outils, a été ajoutée en tant qu'incubateur, et l'API relative à Pac200 a été supprimée.

Les différences d'API sont résumées ici. DRAFT: API Differences Between Java SE 13 (build 33) & Java SE 14 (build 36)

349: JFR Event Streaming

L'enregistreur de vol est un outil de collecte de métriques utile pour l'analyse en cas de panne, mais il nécessite l'analyse des fichiers de vidage, ce qui n'est pas pratique à des fins de surveillance. JFR Event Streaming ajoute des fonctions de surveillance faciles à utiliser, telles que l'enregistrement d'événements.

L'exemple JEP montre un exemple d'enregistrement d'événement, mais j'y ai ajouté la sortie du journal GC.

import java.io.IOException;
import java.time.Duration;
import jdk.jfr.consumer.RecordingStream;
public class JFRStreamTest {
     
    public static void main(String[] args) throws IOException  {
         
        try (var rs = new RecordingStream()) {
            rs.enable("jdk.CPULoad").withPeriod(Duration.ofSeconds(1));
            rs.enable("jdk.JavaMonitorEnter").withThreshold(Duration.ofMillis(10));
            rs.onEvent("jdk.CPULoad", event -> {
                System.out.println(event.getFloat("machineTotal"));
            });
            rs.onEvent("jdk.JavaMonitorEnter", event -> {
                System.out.println(event.getClass("monitorClass"));
            });
            rs.onEvent("jdk.GarbageCollection", System.out::println);
            rs.start();
        }
    }
}

Si vous l'exécutez avec -XX: StartFilghtRecording, Flight Recorder démarrera et les métriques seront affichées périodiquement.

$ java -XX:StartFlightRecording JFRStreamTest.java
Started recording 1. No limit specified, using maxsize=250MB as default.

Use jcmd 79660 JFR.dump name=1 filename=FILEPATH to copy recording data to file.
[1.715s][warning][os] Unable to resolve PDH index: (230)
[1.716s][warning][os] Please check the registry if this performance object/counter is disabled
{
  classLoader = null  name = "jdk/jfr/internal/PlatformRecorder"
  package = {
    name = "jdk/jfr/internal"
    module = {
      name = "jdk.jfr"
      version = "14-ea"
      location = "jrt:/jdk.jfr"
      classLoader = null    }
    exported = true
  }
  modifiers = 49
}

jdk.GarbageCollection {
  startTime = 13:51:48.973
  duration = 12.5 ms
  gcId = 1
  name = "G1New"
  cause = "G1 Evacuation Pause"
  sumOfPauses = 12.5 ms
  longestPause = 12.5 ms
}

Vous pouvez le voir sur JDK Mission Control (JMC). Si vous continuez à exécuter JFR, vous pouvez voir que l'événement est enregistré dans le navigateur d'événements. image.png

370: Foreign-Memory Access API (Incubator)

Il existe des avantages et des inconvénients à accéder à la mémoire en dehors du tas, comme l'utilisation de ByteBuffer, Unsafe et JNI. Lorsque vous utilisez un tampon direct avec ByteBuffer, il est limité à 2 Go qui peuvent être gérés par int, et la libération de la mémoire dépend de GC. Dans le cas de Unsafe, les performances sont bonnes, mais comme son nom l'indique, elles ne sont pas sûres et la JVM plantera si vous accédez à la mémoire libérée. Avec JNI, vous devez écrire du code C et les performances ne sont pas bonnes.

Ainsi, une API qui gère directement la mémoire en dehors du tas a été introduite. Le code ressemble à ceci:

VarHandle intHandle = MemoryHandles.varHandle(int.class);

try (MemorySegment segment = MemorySegment.allocateNative(100)) {
   MemoryAddress base = segment.baseAddress();
   for (int i = 0 ; i < 25 ; i++) {
        intHandle.set(base.offset(i * 4), i);
   }
}

352: Non-Volatile Mapped Byte Buffers

Prend en charge ByteBuffer pour la mémoire non volatile. Un module appelé jdk.nio.mapmode a été introduit, et la classe ʻExtendedMapMode` a été préparée dans le paquet avec le même nom qu'un nouveau MapMode.

Sera ajouté.

var fc = FileChannel.open(path);
fc.map(ExtendedMapMode.READ_WRITE_SYNC, 0, 1024);

C'est comme ressentir. Une exception UnsupportedOperationException est levée si le périphérique n'est pas une mémoire non volatile.

En outre, il semble que BufferPoolMXBean sera capable d'obtenir des statistiques persistantes de MappedByteBuffer sous le nom de «mapped -« mémoire non volatile »».

@PreviewFeature

Les API introduites pour les fonctionnalités de prévisualisation telles que String.formatted étaient obsolètes dans 13. En 14, @ PreviewFeature a été introduit en tant qu'annotation interne, et il a été précisé qu'il s'agit d'une API pour la fonction de prévisualisation. Dans 13, il pourrait être utilisé sans --enable-preview, mais dans 14, si vous utilisez ces API quand --enable-preview n'est pas spécifié,

formatted(java.lang.Object...)Est une API qui fait partie de la fonctionnalité de prévisualisation

J'obtiens une erreur comme celle-ci.

Spécifiez explicitement les champs de méthode liés à la sérialisation avec @Serial

Je définis des champs et des méthodes associés pour les classes qui peuvent être sérialisées, mais bien qu'elles aient une signature fixe, elles ne sont pas vérifiées au moment de la compilation et je n'ai pas pu confirmer qu'elles sont définies correctement.

private static final long serialVersionUID

https://download.java.net/java/GA/jdk14/docs/api/java.base/java/io/Serial.html https://bugs.openjdk.java.net/browse/JDK-8217698

Prend en charge plusieurs formes de format numérique compact

Un des changements qui n'est pas JEP. Dans le cas de l'allemand ou de l'italien, il existe des variations comme Million ou Millionen en 1 million et 2 millions, et il semble qu'elles y correspondent.

jshell> import java.text.*

jshell> var cnf = CompactNumberFormat.getCompactNumberInstance(Locale.GERMAN, NumberFormat.Style.LONG)
cnf ==> java.t[email protected]

jshell> cnf.format(1_000_000)
$3 ==> "1 Million"

jshell> cnf.format(2_000_000)
$4 ==> "2 Millionen"

Il existe également un constructeur qui vous permet de définir vos propres règles selon les règles du pluriel du langage Unicode (https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules).

Ajout d'une méthode pratique à StrictMath

Une méthode pratique a été ajoutée à StrictMath. Avez-vous cherché à faciliter l'utilisation des références de méthodes?

Incrémenter, décrémenter, inversion de signe, mais en cas de dépassement J'obtiens une erreur.

jshell> StrictMath.incrementExact(3)
$5 ==> 4

jshell> StrictMath.incrementExact(Integer.MAX_VALUE)
|Exception java.lang.ArithmeticException: integer overflow
|        at Math.incrementExact (Math.java:968)
|        at StrictMath.incrementExact (StrictMath.java:849)
|        at (#4:1)

jshell> StrictMath.negateExact(Integer.MAX_VALUE)
$6 ==> -2147483647

jshell> StrictMath.negateExact(Integer.MIN_VALUE)
|Exception java.lang.ArithmeticException: integer overflow
|        at Math.negateExact (Math.java:1044)
|        at StrictMath.negateExact (StrictMath.java:909)
|        at (#7:1)

Un débordement se produit avec les opérateurs normaux.

jshell> Integer.MAX_VALUE+1
$8 ==> -2147483648

jshell> Integer.MIN_VALUE
$9 ==> -2147483648

jshell> -Integer.MIN_VALUE
$10 ==> -2147483648

outil

En tant que changement d'outil, l'ajout de jpackage est important. 343: Packaging Tool (Incubator) 367: Remove the Pack200 Tools and API

343: Packaging Tool (Incubator)

Un outil de création de programmes d'installation pour les applications Java a été ajouté. Des API associées ont également été ajoutées, mais il s'agit d'un module d'incubateur. Windows nécessite light.exe et candle.exe, vous devez donc les télécharger à partir de https://wixtoolset.org et les ajouter à votre PATH.

Essayons de créer un programme d'installation pour l'application suivante.

import javax.swing.*;
public class App {
    public static void main(String[] args) {
        var f = new JFrame("My App");
        var t = new JTextArea();
        f.add(t);
        var b = new JButton("Hello");
        b.addActionListener(al -> t.append("Hello!\n"));
        f.add("North", b);
        f.setSize(500, 400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }
}

L'application doit être un fichier Jar.

$ javac App.java
$ mkdir target
$ jar cf target/app.jar App.class
$ jpackage --name myapp --input target --main-jar app.jar --main-class App

Cela créera un programme d'installation de 45 Mo avec le nom myapp.exe pour Windows. Dans le cas d'un JAR modulaire, le runtime Java des seuls modules requis sera installé automatiquement, mais comme j'ai créé un fichier Jar qui ne prend pas en charge les modules ici, il est petit si vous créez le runtime Java minimum à l'aide de jlink. Vous pourrez créer un installateur.

$ jdeps --list-deps App.class
java.base
java.desktop
$ jlink --add-modules java.base,java.desktop --output jre
$ jpackage --name myapp --input target --main-jar app.jar --main-class App --runtime-image jre

Cela a réduit la taille du programme d'installation à 27 Mo. La taille de l'application après l'installation est également réduite de 124 Mo à 74 Mo. Pour Windows, il est préférable d'ajouter --win-menu pour ajouter l'application au menu Windows.

367: Remove the Pack200 Tools and API

Pack200 était un outil pour compresser efficacement les fichiers Jar, mais il sera supprimé car son cas d'utilisation principal, Applet, n'est plus utilisé et n'est plus utilisé. Les API associées sous java.util.jar seront également supprimées.

GC Il y a eu cinq PEC de changements liés à GC. 363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector 364: ZGC on macOS 365: ZGC on Windows 366: Deprecate the ParallelScavenge + SerialOld GC Combination 345: NUMA-Aware Memory Allocation for G1

363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector Concurrent Mark & Sweep GC est supprimé du code source. Il était obsolète dans JEP 291 de Java 9, mais personne ne semble prendre en charge la maintenance, je vais donc le supprimer. Ce faisant, on s'attend à ce que les coûts de maintenance du GC soient réduits et que le développement d'autres GC soit accéléré.

364: ZGC on macOS/365:ZGConWindows

ZGC, qui ne prenait auparavant en charge que Linux, prend désormais en charge macOS et Windows. Initialement, il était supposé que ZGC serait utilisé uniquement sur les serveurs Linux de production, et macOS et Windows ne seraient utilisés qu'à des fins de développement, mais comme il y avait des demandes telles que la volonté d'exécuter l'EDI sur ZGC, macOS et Windows sont également pris en charge. Il semble qu'il ait été décidé de le faire. Windows est compatible avec Windows 10 ver 1803 ou version ultérieure. ZGC utilise un mécanisme pour accéder à la mémoire physique avec plusieurs adresses en utilisant des adresses virtuelles, mais il semble que ZGC puisse être utilisé même sous Windows car la mémoire de fichier d'échange est prise en charge à partir de 1803 sous Windows.

366: Deprecate the ParallelScavenge + SerialOld GC Combination

La combinaison de Prallel pour le GC dans la zone Young et Serial pour le GC dans la zone Old, qui est rarement utilisée mais difficile à maintenir, a été déconseillée.

345: NUMA-Aware Memory Allocation for G1 Récemment, l'architecture NUMA (Non-Uniform Memory Access), dans laquelle l'accès mémoire de chaque cœur n'est pas égal, s'est généralisée. Parallel GC a pris en charge NUMA, mais pas G1. Avec ce JEP, G1 prend également en charge NUMA. Cependant, le système d'exploitation pris en charge est uniquement Linux.

JDK Les modifications liées au JDK lui-même sont liées au formulaire de publication et à la politique de construction. La prise en charge de Solaris et SPARC est désormais obsolète dans Java 14. 362: Deprecate the Solaris and SPARC Ports

362: Deprecate the Solaris and SPARC Ports La prise en charge de Solaris / SPARC, Solaris / x64 et Linux / SPARC sera supprimée. Comme pour la suppression du CMS, si vous pouvez montrer qu'il y a beaucoup de demande, elle sera retirée. Il s'agit également du développement d'OpenJDK en tant qu'open source, et il est possible que le support continu des distributions commerciales telles que Oracle JDK se poursuive. Il semble que les frais de licence Java ne seront pas un problème si vous introduisez Solaris / SPARC.

Recommended Posts

Résumé des nouvelles fonctionnalités de Java 12
Résumé des nouvelles fonctionnalités de Java 13
Résumé des nouvelles fonctionnalités de Java 10
Résumé des nouvelles fonctionnalités de Java 14
Résumé des connaissances Java
Résumé des génériques Java
Résumé relatif à Java
java1.8 nouvelles fonctionnalités
[Résumé] Par exemple, préparation de l'environnement Java
3ème résumé efficace de Java
Java statique [Résumé personnel]
Fonctionnalité d'expression lambda Java 8
Résumé des threads sûrs ~ Java ~
Résumé personnel sur Java
Nouveautés de Java 8
Récapitulatif de la nouvelle fonction JSF2.3
résumé des expressions régulières java
Nouveautés de Java 9,10,11
Résumé du support Java 2018
Résumé du modèle de conception Java
Résumé du mot réservé Java
Résumé approximatif du flux Java8
Résumé des révisions (nouveaux problèmes de yuan) par version Java
Qu'est-ce que l'assertion Java? Résumé.
[Java] Nouvelle méthode de génération de threads (2)
[Java11] Résumé du flux -Avantages du flux-
Révision et résumé de Progate Java (débutant)
Nouvelles fonctionnalités de Java7 à Java8
[Java] Résumé des expressions régulières
[Java] Résumé des opérateurs (opérateur)
Flux Java8, résumé de l'expression lambda
Résumé orienté objet par les débutants (Java)
Résumé des bases du langage Java
Astuces Java - Résumé de l'exécution de Spring
Résumé de la classe Java Math
Résumé des nouvelles fonctionnalités de PrimeFaces 6.0.x
[Java11] Résumé de l'utilisation du flux -Basics-
[Java] Résumé de la syntaxe de contrôle
Résumé du traitement des erreurs Java
[Java] Résumé des modèles de conception
[Java] Nouvelle méthode de génération de threads (1)
[Java] Résumé des opérations mathématiques
Nouvelle syntaxe pour les instructions Java 12 Switch
Considération sur le cadre de persistance Java 2017 (résumé) -1
[Pour les débutants] Résumé du constructeur java
Date de sortie de Java et résumé EOL
Nouvelles fonctionnalités de Java 9 et exemple de code
Résumé
Résumé de l'algorithme AtCoder 400 points (édition Java)
Java
Récapitulatif du problème Java "Pass by Reference"
Java
Résumé de la programmation orientée objet utilisant Java
[Java Silver] Résumé des points de modification d'accès
Résumé de la session d’étude interne des recrues [Java]
Comment créer un résumé de calendrier Java
Mémorandum du nouveau diplômé SES [Java basics]
[java] Résumé de la gestion des caractères
Récapitulatif des modifications autres que JEP de Java10
J'ai essayé le nouveau yuan à Java