Java : les bases pour bien démarrer (types, objets, collections, null)
Les fondations du langage Java expliquées clairement : types primitifs vs objets, la JVM, les collections, la gestion de null, et les pièges classiques du débutant.
Java reste, plus de 25 ans après sa création, l'un des langages les plus utilisés au monde — porté par sa robustesse, son écosystème et sa présence dans l'entreprise et sur Android. Ce guide pose les fondations pour bien démarrer, en évitant les pièges classiques du débutant.
« Write once, run anywhere » : la JVM
Le code Java n'est pas compilé directement en instructions machine, mais en bytecode, exécuté par la machine virtuelle Java (JVM). C'est ce qui rend Java portable : le même .class tourne sur Windows, Linux ou macOS tant qu'une JVM y est installée. La JVM apporte aussi le ramasse-miettes (garbage collector) qui libère automatiquement la mémoire — vous n'avez pas à gérer les allocations à la main comme en C.
Types primitifs vs objets
Java distingue deux familles. Les types primitifs (int, long, double, boolean, char…) contiennent directement une valeur et vivent sur la pile. Les objets (tout le reste, dont String) sont des références vers des données sur le tas.
int a = 5; // primitif : la valeur 5
Integer b = 5; // objet : une référence (autoboxing)
String nom = "Ada"; // objet
// Piège classique : comparer des objets avec ==
String x = new String("hi");
String y = new String("hi");
System.out.println(x == y); // false ! (deux références différentes)
System.out.println(x.equals(y)); // true (même contenu)
Règle d'or : pour comparer le contenu d'objets, utilisez .equals(), jamais == (qui compare les références). Pour les primitifs, == compare bien les valeurs.
Le null, « l'erreur à un milliard de dollars »
Une référence peut valoir null (elle ne pointe vers rien). Appeler une méthode dessus lève la fameuse NullPointerException. Depuis Java 8, Optional exprime proprement « peut-être une valeur, peut-être rien » :
Optional<User> u = repo.findById(id);
String nom = u.map(User::getNom).orElse("Inconnu");
Évitez de renvoyer null depuis vos méthodes : renvoyez un Optional, une liste vide, ou levez une exception explicite.
Les collections : votre boîte à outils quotidienne
Le framework Collections structure les regroupements de données. Les trois à connaître d'abord :
List(ex.ArrayList) — séquence ordonnée, doublons autorisés, accès par index.Set(ex.HashSet) — pas de doublons, sans ordre garanti.Map(ex.HashMap) — associations clé → valeur, la structure la plus utile au quotidien.
Map<String, Integer> stock = new HashMap<>();
stock.put("pommes", 12);
stock.merge("pommes", 3, Integer::sum); // 15
int n = stock.getOrDefault("poires", 0); // 0, sans NPE
Les streams : traiter des données de façon déclarative
Depuis Java 8, les streams permettent d'exprimer des traitements de collections de façon lisible, façon « pipeline » :
List<String> noms = users.stream()
.filter(u -> u.age() >= 18)
.map(User::nom)
.sorted()
.toList();
Pièges fréquents du débutant
- Comparer des
String/objets avec==au lieu de.equals(). - Modifier une collection pendant qu'on la parcourt (
ConcurrentModificationException). - Confondre
intetInteger(l'auto-unboxing d'unIntegernull lève une NPE). - Ignorer les exceptions vérifiées au lieu de les gérer.
Pour aller plus loin
Une fois ces bases acquises, explorez les records (classes de données immuables concises), les enums, les génériques (<T>), la gestion des exceptions et les bases de la concurrence. Installez un bon JDK (Temurin, Corretto), un IDE (IntelliJ IDEA) et pratiquez : Java se maîtrise en écrivant du code, pas en le lisant.