Mieux connaître les nouveautés du langage Java 11, 13 …

Depuis que Java 9 est sorti en Septembre 2017, Oracle livre une nouvelle version de Java tous les 6 mois. Chaque version apporte son lot de nouveautés au langage, aux outils ainsi que des améliorations de performance.

Par exemple Java 9 a amélioré la Javadoc en supportant HTML5 et en ajoutant un champs de recherche.

Avec la Javadoc du JDK, il nous est possible de consulter les classes par module, de restreindre l’affichage à Java SE ou au JDK, de ne voir que les méthodes d’instance d’une classe ou encore de les voir toutes.

Par contre rien n’existe pour filtrer les méthodes ou les classes ajoutées par exemple dans Java 11. La mention since: est bien présente mais c’est tout.

Lister les méthodes nouvelles d’une classe …

Puisque la Javadoc du JDK ne fait pas usage de la mention de version indiquée dans les sources pour les méthodes et les classes:

*
* @since 9
*/

j’ai écrit un programme Java qui va chercher cette information.

Il s’utilise en ligne de commande, utilise Picocli et est disponible dans mon catalogue JBang sur GitHub.

Le principe est très simple, on donne:

  • le répertoire des sources du JDK que l’on souhaite analyser
  • la version de Java pour laquelle on souhaite connaître les nouveautés du langage
  • ainsi qu’une liste de classes qui nous intéresse

Méthodes ajoutées à java.util.stream.Stream en Java 9

Par exemple, quelles méthodes ont été ajoutées à la classe Stream en Java 9:

$ jbang whats-new-in-java@grumpyf0x48 -s /usr/lib/jvm/openjdk-11 -r 9 java.util.stream.Stream
public interface Stream<T> extends BaseStream<T, Stream<T>> // since 1.8
{
	default Stream<T> takeWhile(Predicate<? super T> predicate); // since 9
	default Stream<T> dropWhile(Predicate<? super T> predicate); // since 9
	public static<T> Stream<T> ofNullable(T t); // since 9
	public static<T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next); // since 9
}

Cela suppose d’avoir installé le paquet des sources du JDK de votre système Linux.

Par exemple sur Ubuntu:

$ sudo apt-get install openjdk-11-source
$ cd /usr/lib/jvm/openjdk-11
$ sudo unzip src.zip

Changements sur la classe java.util.Optional depuis java 8

Pour connaître l’évolution de la classe java.util.Optional depuis Java 8:

$ jbang whats-new-in-java@grumpyf0x48 -s /usr/lib/jvm/openjdk-11 java.util.Optional
public final class Optional<T> // since 1.8
{
	public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction); // since 9
	public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier); // since 9
	public Stream<T> stream(); // since 9

	public T orElseThrow(); // since 10

	public boolean isEmpty(); // since 11
}

Les méthodes sont groupées et triées par version du JDK pour mieux voir l’évolution d’une classe.

Classes modifiées en Java 9 dans le package java.time

On peut aussi ne lister que les classes modifiées:

$ jbang whats-new-in-java@grumpyf0x48 --source-path /usr/lib/jvm/openjdk-11 --only-class-names --release 9 java.time.*
public final class OffsetTime // since 1.8
public final class LocalDate // since 1.8
public final class LocalTime // since 1.8
public final class DateTimeFormatterBuilder // since 1.8
public final class Duration // since 1.8
public interface Chronology extends Comparable<Chronology> // since 1.8
public final class IsoChronology extends AbstractChronology implements Serializable // since 1.8

… directement dans votre terminal

On vient de le voir, cette commande ligne affiche les nouvelles méthodes du JDK dans le Terminal, et afin d’avoir un aspect visuel plus agréable, on peut l’utiliser avec la commande bat:

$ jbang whats-new-in-java@grumpyf0x48 -s /usr/lib/jvm/openjdk-11 java.util.Optional | batcat --language java

C’est un peu plus sympa comme ça !

Toutes les options

Par défaut le programme:

  • n’affiche que les classes modifiées dans la ou les versions indiquées
  • n’affiche pas les classes abstraites
  • affiche les méthodes avec chaque classe modifiée
  • affiche les changements en Java 9, 10 et 11
  • effectue ses recherches dans le module java.base

Ce comportement est modifiable comme indiqué dans l’aide:

$ jbang whats-new-in-java@grumpyf0x48 --help
Usage: WhatsNewInJava [-abchvV] [-m=<module>] [-s=<sourcesPath>]
                      [-r=release]... <classNames>...
Display methods added to a Java class in a given JDK release
      <classNames>...      Class names or regexps
  -a, --not-modified-classes
                           Show all classes even not modified ones (default:
                             false)
  -b, --show-abstract-classes
                           Show abstract classes (default: false)
  -c, --only-class-names   Show only names of modified classes, not their
                             methods (default: false)
  -h, --help               Show this help message and exit.
  -m, --module=<module>    Module (java.base, java.desktop, java.logging ...)
                             where to search classes (default: java.base)
  -r, --release=release    JDK release (1.8, 9, 10, 11 ... or ALL) (default: 9,
                             10, 11)
  -s, --source-path=<sourcesPath>
                           JDK sources path (default: /usr/lib/jvm/openjdk-11)
  -v, --verbose            Activate verbose mode (default: false)
  -V, --version            Print version information and exit.

Les limites

Comme le programme parse les sources du JDK à la recherche de la mention @since ..., les méthodes qui en sont dépourvues ne seront pas trouvées.

Également, le parsing étant basique, il se peut que la signature de certaines méthodes ou constructeurs, notamment quand ils sont définis sur plusieurs lignes dans le code, soit incorrecte.

La motivation

Écrire ce programme de recherche des méthodes et des classes modifiées dans le JDK permet aussi de pratiquer (encore) l’utilisation des Stream, et d’utiliser quelques améliorations intéressantes de Java depuis la version 8 comme:

  • Le parcours du systèmes de fichiers avec l’API nio de Java 8
  • Les méthodes de la classe Files
  • La syntaxe var de Java 10
  • Les nouvelles méthodes strip et stripLeading de la classe String en Java 11
  • La nouvelle méthode not de la classe Predicate en Java 11

En outre le programme illustre l’écriture d’un Spliterator, qui est un excellent exercice à faire sur les Stream.

Il permet donc non seulement de lister les nouveautés dans le langage Java mais aussi d’apprendre et de pratiquer ces changements afin de mieux les connaître, et de les faire connaître.

Enfin, pour ceux qui n’ont pas encore utilisé JBang et la possibilité de celui-ci de regrouper plusieurs scripts ensemble dans un catalogue, c’est peut-être l’occasion de s’y mettre !

Code

Le source du programme WhatsNewInJava présenté ici est sur GitHub.