Écosystème de programmation I
Dans ce cours, nous examinons les bases de la séparation des responsabilités à l’aide des ensembles de code (packages) et la façon dont le code provenant de packages externes, ainsi que les artéfacts situés à l’extérieur du classpath original, peuvent être accessibles. Nous terminons ensuite par un survol des bibliothèques standards et un aperçu rapide des environnements de développement intégrés (IDE).
Essentiel du cours
Soyez prudent avec les importations, ne copiez pas de bibliothèques directement dans votre code, et utilisez un StringBuilder lorsque vous concaténez des chaînes de caractères à répétition.
Modules et imports
Un bon programme est modulaire, c’est-à-dire qu’il ne s’agit pas d’un seul gros bloc contenant tout le code dans une
seule classe.
Mais au bout du compte, il faut s’assurer que les différents composants puissent encore interagir entre eux. Cela
soulève quelques questions clés :
- Quel est l’intérêt de modulariser le code et quelle est la pertinence du contexte ?
- Pourquoi n’est-il pas possible pour n’importe quel composant d’utiliser ceux d’autres modules, et que faire si un tel accès est nécessaire ?
- Pourquoi ne puis-je pas simplement appeler une bibliothèque trouvée sur Internet ?
Qu’est-ce qu’un import, au juste ?
Pour les débutants, l’instruction import est souvent perçue comme « quelque chose qu’il faut écrire au début de la
classe pour que le message d’erreur disparaisse ».
Pour répondre à la question « pourquoi avons-nous besoin des imports ? » (ne serait-il pas plus simple si tout était
importé automatiquement ?), nous allons examiner les principes de base suivants :
- Comment le contexte du code est structuré en
packages Java, et pourquoi c’est important. - Pourquoi vous devez importer certaines classes mais pas d’autres, et les exceptions à cette règle.
- Pourquoi il n’est pas conseillé d’importer plus que le strict nécessaire.
Rappel sur les packages
- Java organise le code en packages
- Les packages fournissent un contexte pour un ensemble de classes connexes.
- Exemple :
Mouse.classpeut être une classe imitant le comportement d’une souris biologique, ou bien une classe gérant un périphérique d’entrée humain. - Les packages environnants
animalsetdevicespermettent d’éliminer l’ambiguïté.
- Par défaut, vous ne pouvez accéder qu’aux classes définies dans le même package (ou dans
java.lang).- Exemple : Lorsqu’on travaille dans le package
animals, l’instructionnew Mouse()n’est pas ambiguë — elle créera toujours la classe imitant le comportement d’une souris biologique.
- Exemple : Lorsqu’on travaille dans le package
---
title: Example of ambigous context
---
classDiagram
namespace animal {
class Mouse {
+String species
+void squeak()
}
}
namespace devices {
class Ꮇouse {
+String brand
+void click()
+void scroll()
}
}
Importations
- Par défaut, il n’est pas possible d’instancier (ou même d’appeler) des classes situées à l’extérieur de votre package
actuel.
- Cela vous protège contre les ambiguïtés accidentelles.
- Exemple : Lorsque vous travaillez à l’extérieur des packages
animalsetdevices, que devrait-il se passer si vous créez unnew Mouse()? Il n’est pas clair de quelle classe il s’agit.
- Les importations vous permettent d’étendre le contexte de votre package courant en y ajoutant des classes
supplémentaires :
import animals.Mousevous permettra d’utiliser le modèle de la souris biologique (new Mouse()), mais pas celui du périphérique d’entrée humain.
classDiagram
namespace animals {
class Mouse {
+String species
+void squeak()
}
}
namespace devices {
class Ꮇouse {
+String brand
+void click()
+void scroll()
}
}
class Main
Mouse <.. Main: import
Illustration de
Mainutilisant une instructionimport animals.Mouse.
Pourquoi les packages et les imports sont-ils des antagonistes sémantiques ?
Les packages définissent des frontières de contexte, tandis que les imports étendent ces frontières existantes.
Qu’en est-il de String
Il existe certaines classes qui n’ont pas besoin d’être importées, c’est-à-dire que vous pouvez les utiliser dans votre
code sans ajouter explicitement une instruction import, même si elles ne font pas partie du package courant.
Un exemple est String. Lorsque vous avez écrit votre premier programme « HelloWorld », vous avez défini une chaîne de
caractères et appelé la classe System, mais vous n’avez eu besoin d’aucune importation :
// No import for String required here...
public class HelloWorld
{
public static void main(String[] args)
{
System.out.println("Hello, world!");
}
}
Mais nous venons tout juste d’apprendre que l’appel à une classe externe nécessite une importation. Que se passe-t-il ici ?
Il existe une exception à la règle
java.lang.* est importé automatiquement. Les classes de ce package sont tellement courantes que toutes sont accessibles par défaut : String, System, Math, etc.
L’astérisque
Les importations ne sont pas nécessairement limitées à une seule classe : vous pouvez aussi utiliser le caractère
générique * pour importer tout un package.
ca.quam.mgl7010.animals.*importera tous les éléments présents dans le package.- Cependant, il est généralement déconseillé d’utiliser les caractères génériques.
Que pourrait-il arriver en utilisant un caractère générique (*) ?
Les caractères génériques importent tout le contenu d’un package. Que se passe-t-il si le contenu du package change (par exemple, si une nouvelle classe y est ajoutée) et qu’un conflit survient avec quelque chose que vous importiez déjà ? Il vaut mieux importer uniquement ce dont vous avez réellement besoin — évitez les importations inutiles.
Rappel sur le classpath
- L’instruction
importpermet d’accéder à des classes connues de la JVM, qui seraient autrement hors contexte.- « Connue de la JVM » signifie : une classe présente sur le classpath (une variable qui indique tous les répertoires que la JVM parcourt pour trouver des classes).
Classpath et importations
Vous ne pouvez importer que ce qui se trouve sur le classpath. Si vous trouvez une bibliothèque utile sur Internet, vous ne pouvez pas simplement l’importer sans l’avoir d’abord téléchargée et ajoutée à votre classpath. La JVM ne peut pas explorer Internet pour vous !
Étendre le classpath
- Étendre le classpath est simple : il suffit d’ajouter l’argument
-cp(classpath) pour indiquer toute bibliothèque supplémentaire que vous souhaitez rendre disponible dans votre projet. - Si vous devez ajouter plusieurs dossiers, séparez-les à l’aide du caractère
:. - N’oubliez pas d’inclure le répertoire de votre projet (
.), sinon votre classpath ne contiendra pas vos propres sources et la JVM ne pourra plus trouver votre programme.
Exemple : GSON
Supposons que je veuille utiliser la bibliothèque GSON :
import com.google.gson.Gson; // <-- Import is mandatory, Gson class is not in same package.
class MainWithGson
{
public static void main(String[] args)
{
// Create student
Student myStudent = new Student(34, "Maximilian", "Schiedermeier");
// Export student
String jsonString = new Gson().toJson(myStudent);
System.out.println(jsonString);
}
}
- L’importation
com.google.gson.Gsonseule n’est pas suffisante. - Mais je ne veux pas non plus copier-coller le code source de la bibliothèque GSON dans mon projet !
(Cela n’est d’ailleurs pas toujours possible, car tout le code n’est pas open source.)
Comment indiquer à la JVM où trouver GSON ? (Sans système de build, sans IDE)
Je dois obtenir le fichier JAR de la bibliothèque et étendre le classpath de la JVM : je télécharge le fichier JAR de la bibliothèque et je l’ajoute au classpath, à la fois pour la compilation et pour l’exécution :
wget https://repo1.maven.org/maven2/com/google/code/gson/gson/2.13.1/gson-2.13.1.jar
javac -cp gson-2.13.1.jar *.java
java -cp gson-2.13.1.jar:. MainWithGson
Accès aux bibliothèques standard
Pour récapituler : voici un tableau qui résume si un import ou une extension du classpath est nécessaire :
| Code auquel on veut accéder | Action nécessaire depuis la classe actuelle |
|---|---|
| Accéder à une classe du même package | Aucune, fonctionne directement |
Accéder à une classe du package java.lang |
Aucune, fonctionne (exceptionnellement) par défaut |
| Accéder à une classe d’un autre package du projet | Importation nécessaire |
| Accéder à une classe d’une bibliothèque externe | Importation et extension du classpath nécessaires |
Règle générale d’extension du classpath
- Si la classe cible se trouve à l’intérieur du projet, aucune extension du classpath n’est nécessaire.
- Si la classe cible se trouve à l’extérieur du projet, une extension du classpath est nécessaire.
Et comme souvent dans la vie, il existe une exception : l’accès aux classes de la bibliothèque standard.
Exemples :
StringMathSystem- ...
Notre programme « Hello, World! » en est un exemple parfait. Aucune extension du classpath n’est nécessaire pour compiler ou exécuter ce projet.
Les bibliothèques standard comme partie intégrante de l’installation Java
Mais attendez ! Le tableau ci-dessus indique que les classes externes au projet doivent être ajoutées au classpath.
Qu’en est-il alors de la classe String ? Nous ne l’avons pas définie dans notre projet...
Aucune nécessité d’ajouter manuellement les bibliothèques standard au classpath
Certaines classes sont tellement utiles et universelles qu’il est presque certain que vous en aurez besoin dans n’importe quel projet. Par commodité, ces classes (appelées bibliothèques standard) sont toujours incluses dans le classpath. Ainsi, le classpath par défaut couvre déjà deux emplacements : votre projet et les bibliothèques standard (qui ne se trouvent pas dans votre projet).
Une question logique suit : « Si les classes des bibliothèques standard ne sont pas dans mon projet, d’où proviennent-elles exactement ? »
- Les classes des bibliothèques standard (
String,Math,System, etc.) font partie de votre installation Java. - Lorsque vous installez Java (c’est-à-dire la commande
java, la JVM, le compilateur, etc.), vous obtenez également une copie de toutes les classes de la bibliothèque standard. - Vous pouvez effectivement retrouver ces classes dans le répertoire d’installation.
- L’emplacement exact varie selon le système d’exploitation, mais il est accessible via la variable JAVA_HOME.
- Cependant, ces classes ne sont pas stockées sous forme de fichiers séparés : pour économiser de l’espace, elles sont
regroupées dans un format compressé :
- Dans les anciennes versions, les classes faisaient partie d’un fichier JAR (Java Archive) dans le répertoire d’installation.
- Dans les versions plus récentes, un système de fichiers Java spécial est utilisé pour la compression. La
commande
jimage(fournie avec Java) permet d’explorer le contenu compressé des modules de la bibliothèque standard.
jimage est déjà installé
jimage est un outil Java pour inspecter le contenu des modules Java compressés. Vous n’avez pas besoin de l’installer.
Avec tout ce que vous venez d’apprendre sur les importations et le classpath, voici une question (style examen) pour tester votre compréhension :
Y a-t-il des classes externes qui ne nécessitent pas d’extension du classpath, mais d'un import ?
Oui ! Nous venons d’apprendre que toute classe de la bibliothèque standard (String, Math, System) est automatiquement sur le classpath. Mais nous avons également appris que seules les classes du package java.lang sont importées automatiquement. Il reste donc de nombreuses classes qui sont automatiquement sur le classpath, mais nécessitent quand même un import. Des exemples sont List et Set.
Bibliothèques standard
Maintenant que nous avons pris connaissance des bases techniques pour accéder aux classes de la bibliothèque standard ( ou à d’autres classes externes), examinons une sélection de classes fournissant des solutions testées et éprouvées pour des problèmes de programmation courants.
Collections
Les débutants en programmation sont souvent obsédés par les tableaux, car ils ont une syntaxe simple et offrent une
solution primitive pour organiser des données.
Bien que les tableaux soient une solution respectable pour de nombreux problèmes, ils sont particulièrement inadaptés
lorsque :
- Vous ne savez pas combien d’objets vous aurez : vous risquez soit de gaspiller des ressources, soit de devoir réallouer un tableau plus grand et tout copier ensuite.
- Vous voulez trouver rapidement un objet spécifique : vous devrez implémenter votre propre stratégie de recherche pour un tableau.
- Vous avez besoin d’insertion ou de suppression fréquente au milieu : vous devrez déplacer de nombreux éléments du tableau.
- Vous avez besoin de modifications concurrentes : les tableaux ne sont pas thread-safe, vous ne pouvez pas avoir deux threads modifiant les données en même temps.
Nous allons maintenant parcourir brièvement quelques alternatives. La bibliothèque standard Java contient diverses
classes permettant de stocker des données dans des structures de données standard. Celles-ci font toutes partie du
package collections.
Il n’existe pas de solution universelle
Tout comme les tableaux ne conviennent pas à tous les problèmes, aucune des classes fournies par le framework collections n’est optimale dans toutes les situations. En tant qu’ingénieur logiciel, il est important d’adapter la solution choisie aux caractéristiques du problème (et non l’inverse !)
Listes
Les listes sont comme des trains : vous pouvez facilement ajouter ou retirer des éléments (wagons), mais la seule façon d’accéder à un élément spécifique est de parcourir tout le train.
Il n’existe pas d’objet List
List est une interface, c’est-à-dire que vous ne pouvez créer que des sous-types d’implémentation, par exemple LinkedList :
Créer et rechercher dans une liste :
// Creating a new (empty list)
List chooChooTrain = new LinkedList<Wagon>();
chooChooTrain.add(new Wagon("Black"));
chooChooTrain.add(new Wagon("Red"));
chooChooTrain.add(new Wagon("Gold"));
// Searching for the gold a wagon
Iterator<Wagon> wagonIterator = chooChooTrain.iterator();
while (wagonIterator.hasNext()) {
Wagon currentWagon = wagonIterator.next();
if (currentWagon.getColour().equals("Gold")) {
System.out.println("Found it!");
}
}
Sets
Les sets (ensembles), contrairement aux listes...
- n’autorisent pas les doublons.
- n’ont pas d’ordre.
Cela signifie que...
- Ajouter plusieurs fois le même élément n’a aucun effet (l’élément est déjà présent).
- Remplir les éléments dans un ordre particulier n’a pas d’importance.
Principe de base
Utilisez un ensemble si la seule chose qui compte est la présence d’un élément.
Exemple : destinataires d’un courriel
- Il est inutile d’ajouter un destinataire deux fois (recevoir le courriel une fois suffit).
- Il est inutile d’être listé avant un autre destinataire, tout le monde reçoit le courriel.
Cependant, (tout
comme List), Set
est une interface et ne peut pas être instancié.
Dans la plupart des cas, HashSet est un bon
choix :
- Le hachage est efficace pour éliminer les doublons (table de hachage interne implicite).
- Performances en temps constant pour les opérations de base.
// Create a Set
Set<String> mailingList = new HashSet<>();
// Add a few elements
mailingList.add("luke@alderaan.resistence");
mailingList.add("palpatine@unlimitedpower.coruscant");
mailingList.add("r2d2@astromech.beep");
// Remove an element
mailingList.add("r2d2@astromech.beep");
mailingList.add("yoda@dagobah.mystic"); // nothing bad happen will here
// Check if an element is present
System.out.println(mailingList.contains("luke@alderaan.resistence"));
Maps
- Nous avons déjà brièvement vu les Maps lorsque nous avons travaillé avec les Génériques.
- Les Maps sont souvent également appelées : "Dictionnaire" ou "Hashtable" — ce dernier terme parce qu’elles utilisent souvent des fonctions de hachage en interne pour détecter les clés en double.
- L’exemple le plus courant est le carnet de téléphone, c’est-à-dire une série de paires "clé-valeur" :
- Clé : Nom (généralement unique)
- Valeur : Numéro de téléphone
Crédit image : Wikipedia
Les Maps sont une manière élégante de compenser ce que les Listes et Tableaux n’ont pas : extension dynamique et accès rapide.
Pourquoi n’y a-t-il pas de garanties de performance fiables pour les Maps ?
Parce que, bien que peu probable, toutes les entrées pourraient avoir la même valeur de hachage, annulant tous les avantages de l’indexation par hachage. La map ne serait alors pas plus performante qu’une recherche linéaire dans une liste.
Arbres (Trees)
Les arbres sont plus complexes à implémenter que les Maps, mais offrent de meilleures garanties de performance dans le pire des cas.
- L’accès est rapide, car dans un arbre équilibré, le nombre d’entrées croît de manière exponentielle avec la
profondeur, c’est-à-dire que la navigation vers une entrée spécifique se fait en temps
log(n). - Ils sont plus complexes, car l’ajout de nouveaux éléments peut déséquilibrer l’arbre, nécessitant une réorganisation régulière pour maintenir des performances optimales.
Crédit image : Wikipedia
Gestion des textes
Dans cette section, nous examinerons plusieurs bonnes pratiques liées aux chaînes de caractères et à la bibliothèque standard.
StringBuilder
Les Strings sont des objets immuables, ce qui signifie que chaque modification d’un objet String crée implicitement
un nouvel objet :
- Créer quelques objets n’est pas un problème, mais en créer des milliers peut l’être.
-
Une boucle avec des modifications répétées de
Stringpeut réduire les performances.// Modifying a string 100k times takes about 1 second. final int ITERATIONS = 100_000; String str = ""; long start = System.nanoTime(); // Naïve concatenation, with every iteration for (int i = 0; i < ITERATIONS; i++) { str += i; // creates a new String object every time } // Print delay long end = System.nanoTime(); System.out.println("String: " + (end - start) / 1_000_000 + " ms");
Éviter la création répétée d’objets
Java dispose d’une classe intégrée pour contourner ce problème : StringBuilder.
La classe StringBuilder permet de "construire" (par exemple concaténer) des chaînes de caractères sans créer implicitement de nouveaux objets immuables.
-
Une boucle avec des modifications répétées de
StringBuilderest beaucoup plus rapide que l’équivalent avecString:// Modifying a stringnbuilder 100k times takes about 2 milliseconds. final int ITERATIONS = 100_000; long start = System.nanoTime(); start =System.nanoTime(); // String concatenation, using StringBuilder.append() StringBuilder sb = new StringBuilder(); for(int i = 0; i<ITERATIONS;i++) { sb.append(i); } // Print delay String result = sb.toString(); end =System.nanoTime(); System.out.println("StringBuilder: "+(end -start) /1_000_000+" ms");
Benchmark :
| Itérations | String (ms) | StringBuilder (ms) |
|---|---|---|
| 10k | 28 ms | 0 ms |
| 50k | 307 ms | 2 ms |
| 100k | 1075 ms | 2 ms |
| 200k | 4140 ms | 3 ms |
| 300k | 9518 ms | 4 ms |
| 1M | (crash) | 15 ms |
Benchmark mesuré sur un MacBook Air 2024, 16 Go RAM, processeur M3.
La visualisation ci-dessous des performances mesurées montre que l’implémentation avec String ne scale pas. Le temps
d’exécution double à peu près tous les 60k concaténations, c’est-à-dire que le ralentissement est exponentiel.
Scanner
Pour la gestion des entrées, vous utilisez peut-être
un BufferedReader, enveloppant
un StringReader pour accéder aux entrées
provenant de System.in.
Cela fonctionne, mais ce n’est pas la solution la plus simple :
- Les BufferedReader sont conçus pour des entrées génériques :
- Doivent être enveloppés autour d’un lecteur spécifique aux chaînes
- Doivent gérer les cas particuliers (exceptions, try-catch)
-
Résultat : code verbeux et volumineux
// Boilerplate code, reading user name and age from console with Buffered/String readers. // BufferedReader needs to wrap another Reader, in this case InputStreamReader BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); try { System.out.print("Enter your name: "); String name = reader.readLine(); // readLine() throws IOException System.out.print("Enter your age: "); String ageInput = reader.readLine(); // still returns a String int age = Integer.parseInt(ageInput); // must manually parse System.out.println("Hello " + name + ", you are " + age + " years old."); } catch (IOException e) { System.err.println("Error reading input: " + e.getMessage()); }
Éviter de lire depuis la console avec un BufferedReader.
La lecture depuis la console (et les fichiers texte) est une fonctionnalité standard. Les versions récentes de Java ont introduit une classe de bibliothèque standard utile pour cet usage : le Scanner.
- L’utilisation du Scanner est simple et présente plusieurs avantages, notamment l’absence de gestion d’exceptions nécessaire et le support automatique de la conversion de types :
// Reading name and age from console, using a scanner.
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine(); // No IOException handling needed
System.out.print("Enter your age: ");
int age = scanner.nextInt(); // No manual parsing needed
System.out.println("Hello " + name + ", you are " + age + " years old.");
```
#### Couleurs TTY
* Bien que ce ne soit pas strictement une fonctionnalité Java, les terminaux Unix supportent les couleurs.
* Des préfixes et suffixes de chaînes spéciaux peuvent être utilisés pour activer la sortie colorée dans la console :
| Couleur | Code TTY |
|---------|---------------|
| Rouge | `\033[00;31m` |
| Vert | `\033[00;32m` |
| Jaune | `\033[00;33m` |
| Bleu | `\033[00;34m` |
| Magenta | `\033[00;35m` |
| Cyan | `\033[00;36m` |
| Blanc | `\033[00;36m` |
| Défaut | `\033[00;39m` |
* Exemple :
```java
public static void main(String[] args)
{
System.out.println("\033[00;36m" + "Hello, World!" + "\033[00;39m"));
}
Utilisez une classe wrapper pour colorer vos chaînes
Vous pouvez définir facilement une classe énumération réutilisable pour envelopper n’importe quelle chaîne dans l’une des couleurs TTY par défaut, par exemple : TtyColours.CYAN.wrap("Hello, World!").
IDEs
Dans le meilleur des cas, un IDE sert de front-end pour le langage de programmation et les fonctionnalités de l’écosystème, afin d’augmenter la productivité du développeur, par exemple :
- Navigation dans le code
- Configurations de lancement
- Formatage automatique du code
- Analyse du code en arrière-plan / détection des erreurs de syntaxe
- Suggestions d’amélioration / refactoring
- Complétion de code
- ...
Pour une liste complète des fonctionnalités d’un IDE, voir la conférence INF2050 correspondante. Nous allons ici seulement examiner brièvement les IDE les plus répandus pour l’écosystème Java.
Les IDEs ne réduisent pas la complexité
Les IDEs n’éliminent pas la complexité, ils accélèrent seulement l’accès aux outils. Avant de vous reposer sur un IDE, apprenez à écrire, compiler et exécuter du code avec un simple éditeur et la ligne de commande.
Au-delà de l’éditeur de texte standard
Il est tout à fait possible de coder même de grands projets logiciels avec un éditeur de texte basique. Cependant, cela devient rapidement très inconfortable. Par exemple, vous n’avez pas : la coloration syntaxique, le formatage automatique, les suggestions d’API, la navigation dans le code, … et bien d’autres fonctionnalités.
Et vim, n’est-ce pas un peu un IDE ?
Vim et Emacs sont des éditeurs, écrits par des développeurs pour des développeurs. Vous pouvez tout à fait les utiliser et configurer une longue liste de plugins pour obtenir quelque chose de proche d’un IDE. Cependant, vous risquez de passer plus de temps à configurer votre éditeur qu’à travailler sur votre projet. Correct pour les utilisateurs avancés, mais dans ce cours nous utiliserons un IDE graphique.
Coloration syntaxique
Une fonctionnalité clé de tout IDE est la coloration syntaxique spécifique au langage.
- Les programmes Java doivent être 100 % syntaxiquement corrects, sinon le compilateur rejettera votre code.
- Il est très facile de faire une petite erreur de syntaxe ; votre programme pourrait être rejeté par exemple si vous oubliez un point-virgule :
Repérez l’erreur de syntaxe : System.out.printl("Hello, World!")
En réalité, il y en a deux :
- L’appel de méthode correct est print ou println.
- Point-virgule manquant à la fin de l’instruction.
- Même le développeur le plus expérimenté fait des erreurs de syntaxe.
- C’est pourquoi nous utilisons des outils d’assistance :
- Les IDE analysent automatiquement l’AST pour mettre en évidence toutes les erreurs de syntaxe pendant la frappe.
- Un marqueur rouge sur la barre de défilement indique une erreur de syntaxe.
- Survolez le marqueur ou la ligne pour obtenir une explication de l’erreur, par exemple : "Point-virgule manquant après l’instruction à la ligne 42."
- Dans certains cas, l’IDE suggère même une correction rapide, que vous pouvez appliquer en un simple clic.
Formatage automatique du code
- Le formatage va au-delà de la correction syntaxique.
- Du point de vue du compilateur, les deux extraits de code ci-dessous sont identiques, ils partagent la même structure
AST :
- Code non formaté :
- Code formaté :
- La plupart des humains conviendraient que le deuxième exemple est plus lisible.
- IntelliJ peut formater automatiquement le code pour une meilleure lisibilité :
- Mac OS :
Command (⌘) + Option (⌥) + L - Linux / Windows :
Ctrl + Alt + L
- Mac OS :
Eclipse
Un dinosaure avec de nombreux inconvénients, mais gratuit et couvrant les bases.
Avantages
- Existe depuis toujours, la plupart des développeurs s’en sortent relativement bien.
- Support Java raisonnable.
- Gratuit.
Inconvénients
- Tendance à se corrompre.
- Place les configurations un peu partout (répertoire d’installation, caches, répertoire personnel), sans philosophie ni documentation apparente.
- Les plugins tendent à verrouiller le projet dans l’écosystème Eclipse.
- La configuration de l’IDE est fastidieuse, difficilement automatisable et souvent peu fiable :
Contexte : J’ai travaillé une fois avec un outil académique tellement lié à Eclipse qu’il était presque impossible à utiliser sans passer des heures à cliquer dans les menus Eclipse. L’intégration des nouveaux ingénieurs était très inefficace et j’ai fini par développer un script bash pour configurer automatiquement autant que possible. Le principal problème était qu’Eclipse documente à peine l’emplacement des paramètres sur le disque, ce qui rend le processus fastidieux et laborieux.
JetBrains IntelliJ
Développement Java sérieux, outils professionnels (surtout la version Ultimate).
Avantages
- Une multitude de fonctionnalités extrêmement utiles pour les développeurs avancés.
- Support massif prêt à l’emploi pour la plupart des outils de l’écosystème Java.
- Rarement corrompu, avec un mécanisme pour réparer les installations corrompues.
- Documentation et support extrêmement solides.
- Licences académiques gratuites.
Inconvénients
- La version gratuite manque les fonctionnalités les plus utiles.
- Les fonctionnalités les plus puissantes ne sont pas évidentes à apprendre.
VS-Code
Un éditeur répandu et gratuit, avec de nombreux plugins disponibles.
Avantages
- Gratuit
- Communauté massive
- Plugins pour tout
- Support de code-server (l’IDE entier peut être diffusé comme application web depuis un serveur distant – plus besoin d’installation locale, n’importe quel appareil peut instantanément devenir une machine de développement !)
Utilisez code-server sur GitLab
GitLab inclut une instance de code-server intégrée ! Pour de petites modifications, vous pouvez simplement taper "." pour obtenir un IDE instantané basé sur le navigateur. L’instance GitLab de l’UQAM ne permet cependant pas l’exécution distante.
Inconvénients
- Ne fonctionne pas beaucoup sans au moins cinq plugins installés.
- Trouver les bons plugins n’est pas toujours évident.
- Tous les plugins ne sont pas fiables.
Littérature
Inspiration et lectures complémentaires pour les esprits curieux :
Voici le lien pour accéder à l’unité de labo : Lab 06