Eclipse IDE 2021-06 est sortie
Contexte
La dernière version d’Eclipse 2021-06 (v 4.20) est disponible depuis le 16 juin sur la page de téléchargement, soit seulement 3 mois après la dernière version. L’éco-système java s’adapte et suit les nouveautés du jdk.
Une question subsiste. Où sont passées les petits noms accompagnant les versions d’Eclipse : mars, neon, oxygen ou photon ?
SimRel ?
Les versions ne possède plus de noms, mais l’année suivi du mois de la sortie.
SimRel est la contraction de Simulaneous Release.
C’est à dire que la fondation Eclipse et la communauté des projets s’organisent pour sortir une version coordonnée avec l’ensemble des projets. La page Simultaneous Release donne des informations sur les différentes versions et les références vers le wiki selon la version.
C’est depuis septembre 2018 que Eclipse a choisi de changer sa cadence de sortie avec SimRel:
-
1 version majeur,
-
suivi 3 version de mise à jour (cycle de 13 semaines)
Les treize semaines inclut le planning suivant :
-
3 Versions Milestone (M1/2/3)
-
2 Versions Release Candidate (RC1/2)
-
1 Version disponibilité générale (GA)
Eclipse IDE en chiffres
Pour se remetre en phase avec l’ensemble de ces projets et ses contributeurs. Voici quelques chiffres :
Les nouveautés
-
Support JDK 16 par défaut. Avec cette version, le support de JDK 16 est inclus de base. Ce n’est pas la peine d’ajouter une extension dédiée.
-
Inclusion d’un JRE 16 par défaut Un JDK est fourni par défaut depuis la version 2020-12. Cela permet d’être autonome et de n’avoir pas besoin de pré-requis.
-
Amélioration du terminal Des améliorations ont été portées sur le terminal inclus dans Eclipse
-
Outil de nettoyage de code L’outil disponible dans l’IDE a été enrichie de 12 améliorations. Nous allons le voir dans la section dédiée.
Outil de nettoyage de code
Introduction
Je connais. Je veux voir directement les nouvelles règles
C’est l’occasion de faire un focus sur cet outil. Cela permet d’aller plus loin que le simple formattage. Les propositions sont classées selon les catégories suivantes :
-
Organisation du code
-
Style de code
-
Duplication de code
-
Fonctionnalité Java
-
Accès aux membres
-
Code manquant
-
Optimisation
-
Correction de code
-
Code non nécessaire
La configuration est faite au niveau des préférences. (Allez le menu Java > Code Style > Clean Up). Cela peut être surchargé par projet.
Les nouveautés
Comme mentionné plus haut, l’outil de nettoyage de code vient avec 12 améliorations. Nous allons voir les cas d’usages :
-
(Style de code) Utilisation du mot clé
instanceof
public class Cleanup_1_UtilisationInstanceOf {
public boolean maMethode(Object obj) {
return String.class.isInstance(obj);
}
}
devient
public class Cleanup_1_UtilisationInstanceOf {
public boolean maMethode(Object obj) {
return (obj instanceof String);
}
}
-
(Duplication de code) Factorisation des opérateurs
public class Cleanup_2_FactorisationOperateur {
public boolean maMethode(boolean repetitionBool, boolean isValide, boolean isActive) {
return repetitionBool && !isValide || repetitionBool && isActive;
}
}
devient
public class Cleanup_2_FactorisationOperateur {
public boolean maMethode(boolean repetitionBool, boolean isValide, boolean isActive) {
return repetitionBool && !isValide || repetitionBool && isActive;
}
}
----
-
(Duplication de code) Réorganise les instructions
if
pour éviter la duplication.
public class Cleanup_3_OrganiseIfExterieur {
public void maMethode(boolean isValide, boolean isActive) {
if (isValide) {
if (isActive) {
System.out.println("123");
}
} else if (isActive) {
System.out.println("456");
}
}
}
devient
public class Cleanup_3_OrganiseIfExterieur {
public void maMethode(boolean isValide, boolean isActive) {
if (isActive) {
if (isValide) {
System.out.println("123");
} else {
System.out.println("456");
}
}
}
}
-
(Duplication de code) Une seul instruction
if
au lieu de bloc dupliqué
public class Cleanup_4_UnSeulBlocIf {
public void maMethode(int nombre) {
if (nombre == 0) {
System.out.println("123");
return;
}
if (nombre == 1) {
System.out.println("123");
return;
}
System.out.println("456");
}
}
devient
public class Cleanup_4_UnSeulBlocIf {
public void maMethode(int nombre) {
if ((nombre == 0) || (nombre == 1)) {
System.out.println("123");
return;
}
System.out.println("456");
}
}
-
(Optimisation) Utilisation de la méthode
String.isBlank()
L’appel de la méthode String.strip()
est coûteux car elle nécessite la création d’une instance de String
alors que nous pouvons avoir l’information directement avec la méthode String.isBlank()
public class Cleanup_5_UtilisationIsBlank {
public boolean maMethode(String texte) {
return texte.strip().isEmpty();
}
}
devient
public class Cleanup_5_UtilisationIsBlank {
public boolean maMethode(String texte) {
return texte.isBlank();
}
}
-
(Optimisation) Utilisation de
valueOf()
au lieu du constructeur
Pour rappel, les constructeurs pour ces types de classes "wrapper" sont dépréciés depuis Java 9.
Cela va dans le sens des avertissements supplémentaires de Java 16 sur l’instantiation de ce type de classes (mon billet dédié à la JEP 390)
public class Cleanup_6_UtilisationValueOf {
public void maMethode() {
Byte un = new Byte((byte)4);
Boolean deux = new Boolean(true);
Character trois = new Character('c');
Double quatre = new Double(2.0);
Float cinq = new Float(1f);
Long six = new Long(10);
Short sept = new Short((short)25);
Integer huit = new Integer(1);
}
}
devient
public class Cleanup_6_UtilisationValueOf {
public void maMethode() {
Byte un = Byte.valueOf((byte)4);
Boolean deux = Boolean.valueOf(true);
Character trois = Character.valueOf('c');
Double quatre = Double.valueOf(2.0);
Float cinq = Float.valueOf(1f);
Long six = Long.valueOf(10);
Short sept = Short.valueOf((short)25);
Integer huit = Integer.valueOf(1);
}
}
-
(Optimisation) Utilisation type primitif au lieu de leur pendant objet
Cela évite les phases de "autoboxing/unboxing".
Côté performance, les types primitifs pourront être sur le tas. Cela est plus efficace qu’un appel à des méthodes d’une instance.
public class Cleanup_7_UtilisationTypePrimitif {
public int maMethode(Double nombre) {
Double variableInitialise = new Double("0");
if (variableInitialise.doubleValue() > 0.0) {
System.out.println(variableInitialise.toString() + 1);
}
return variableInitialise.compareTo(nombre);
}
}
devient
public class Cleanup_7_UtilisationTypePrimitif {
public int maMethode(Double nombre) {
double variableInitialise = Double.parseDouble("0");
if (variableInitialise > 0.0) {
System.out.println(Double.toString(variableInitialise) + 1);
}
return Double.compare(variableInitialise, nombre);
}
}
-
(Code non nécessaire) Utilisation de la valeur booléenne plutôt qu''une comparaison
public class Cleanup_8_UtilisationValeurBooleenne {
public void maMethode(boolean isValide) {
if (isValide == true) {
System.out.println("123");
}
}
}
devient
public class Cleanup_8_UtilisationValeurBooleenne {
public void maMethode(boolean isValide) {
if (isValide) {
System.out.println("123");
}
}
}
-
(Organisation de code) Utilisation de comparateur implicite
public class Cleanup_9_UtilisationComparateurImplicite {
public void maMethode(List<Date> listeAtrier) {
Collections.sort(listeAtrier, new Comparator<Date>() {
@Override
public int compare(Date arg0, Date arg1) {
return arg0.compareTo(arg1);
}
});
}
}
devient
public class Cleanup_9_UtilisationComparateurImplicite {
public void maMethode(List<Date> listeAtrier) {
Collections.sort(listeAtrier);
}
}
-
(Code non nécessaire) Creation de tableau avec les accolades
public class Cleanup_10_CreationTableauAvecAccolades {
public int maMethode() {
int[][] tableauEntier = new int[][] { { 42 } };
return tableauEntier.length;
}
}
devient
public class Cleanup_10_CreationTableauAvecAccolades {
public int maMethode() {
int[][] tableauEntier = { { 42 } };
return tableauEntier.length;
}
}
-
(Code non nécessaire) Suppression de la variable avant le retour de la méthode
public class Cleanup_11_SuppressionVariableAvantRetour {
public int maMethode() {
int i = 0;
return i;
}
}
devient
public class Cleanup_11_SuppressionVariableAvantRetour {
public int maMethode() {
return 0;
}
}
-
Remplacer les appels des propriétés par leurs constantes
A noter que ces méthodes existent depuis Java 7.
public class Cleanup_12_RemplacerProprietesParConstante {
public void maMethode() {
String s = System.getProperty("file.separator");
String t = System.getProperty("line.separator");
String u = System.getProperty("file.encoding");
String v = System.getProperty("path.separator");
Boolean x = Boolean.parseBoolean(System.getProperty("ma.propriete"));
}
}
devient
public class Cleanup_12_RemplacerProprietesParConstante {
public void maMethode() {
String s = FileSystems.getDefault().getSeparator();
String t = System.lineSeparator();
String u = Charset.defaultCharset().displayName();
String v = File.pathSeparator;
Boolean x = Boolean.getBoolean("ma.propriete");
}
}
Le tester soi-même.
Pour tester facilement, je vous ai préparé un projet disponible sur github.
pré-requis : Eclipse 2021-06 installé.
Pour cela, il faut réaliser les opérations suivantes :
-
Recupérer le code à partir du dépôt
-
Charger le projet 2021-07-Eclipse-2021-06
-
Charger le fichier de configuration ide/regles-nettoyage-de-code.xml au niveau de l’outil de nettoyage (au niveau des préférences Eclipse)
-
Vous avez les exemples de code de ce billet dans le package
fr.lbenoit.billets.codes_sources.eclipse
, il suffit de réaliser cliquer droit > Source > Clean up…
Profites-en.
Références
-
une video (en anglais) présente les nouveautés.
Moteur de recherche
"Eduquer, ce n'est pas remplir des vases mais c'est d'allumer des feux." - Michel Montaigne
Billets récents
- Eclipse plante systématiquement sous Debian (et autres distribution Linux)
- JEP 463, Implicitly Declared Classes and Instance Main Methods (Second Preview)
- Debian - Montée de version de Debian 11 (Bullseye) à Debian 12 (Bookworm)
- JEP 451, Prepare to Disallow the Dynamic Loading of Agents
- JEP 444, Virtual Threads