Java : machine virtuelle, POO et gestion mémoire
1. Qu'est-ce que Java
Java est un langage orienté objet, statiquement typé, conçu autour du principe "write once, run
anywhere" : le code source est compilé en bytecode, exécuté par une machine virtuelle (JVM) plutôt
que directement par le système d'exploitation. Cela garantit la portabilité entre Windows, Linux et
macOS sans recompilation.
2. La JVM et le cycle de compilation
Le code .java est d'abord compilé par javac en fichiers .class contenant du bytecode, un format
intermédiaire indépendant de la plateforme. Ce bytecode est ensuite interprété, puis progressivement
compilé à la volée (JIT — Just-In-Time compilation) en code machine natif par la JVM, ce qui combine
portabilité et performance proche du code compilé nativement.
javac [Link] # produit [Link]
java Programme # exécute via la JVM
3. Gestion automatique de la mémoire
Java gère la mémoire via un ramasse-miettes (Garbage Collector) qui libère automatiquement les
objets devenus inaccessibles, évitant la gestion manuelle propre à des langages comme C ou C++. La
mémoire se divise principalement entre la pile (stack), qui stocke les variables locales et références, et
le tas (heap), où résident les objets eux-mêmes.
Ce mécanisme réduit les risques de fuites mémoire classiques, mais ne les élimine pas totalement : des
références persistantes non nécessaires (ex. collections statiques qui grossissent indéfiniment) peuvent
encore empêcher la libération d'objets inutilisés.
4. Programmation orientée objet
Java repose entièrement sur le paradigme objet : toute logique s'organise en classes et objets, avec les
quatre piliers classiques — encapsulation, héritage, polymorphisme et abstraction. Contrairement à
PHP ou JavaScript, Java impose un typage statique strict : chaque variable, paramètre et retour de
méthode doit avoir un type déclaré, vérifié à la compilation.
public abstract class Vehicule {
protected String nom;
public abstract void demarrer();
}
public class Voiture extends Vehicule {
@Override
public void demarrer() {
[Link](nom + " démarre");
}
}
5. Gestion des exceptions
Java distingue les exceptions vérifiées (checked exceptions), que le compilateur oblige à gérer
explicitement (try/catch ou déclaration throws), des exceptions non vérifiées (unchecked, héritant de
RuntimeException), qui ne sont pas contrôlées à la compilation. Cette distinction force une gestion
d'erreur plus rigoureuse dès la conception de l'API.
try {
FileReader fichier = new FileReader("[Link]");
} catch (IOException e) {
[Link]("Erreur de lecture : " + [Link]());
} finally {
// nettoyage systématique
}
6. Écosystème et outils de build
L'écosystème Java repose largement sur des outils de build comme Maven ou Gradle, qui gèrent les
dépendances, la compilation et l'empaquetage (JAR/WAR). Pour le développement web backend, le
framework Spring (et notamment Spring Boot) domine largement, en s'appuyant sur l'injection de
dépendances et une architecture modulaire proche du pattern MVC.
7. Sécurité des applications Java
• Désérialisation non maîtrisée d'objets Java, historiquement source de vulnérabilités critiques
• Injections SQL via des requêtes JDBC construites par concaténation plutôt que par requêtes
préparées
• Gestion incorrecte des dépendances tierces, vecteur d'attaque via des bibliothèques vulnérables
(cf. Log4Shell)
• Exposition d'informations sensibles dans les traces d'exception (stack trace) en environnement de
production
La vulnérabilité Log4Shell (CVE-2021-44228), affectant la librairie de journalisation Log4j, illustre
concrètement le risque lié aux dépendances tierces : une simple chaîne de caractères journalisée
pouvait déclencher l'exécution de code arbitraire à distance.
8. Bonnes pratiques
• Préférer la composition à l'héritage profond pour limiter le couplage entre classes
• Utiliser des requêtes préparées (PreparedStatement) pour tout accès JDBC
• Maintenir les dépendances à jour et auditer régulièrement les vulnérabilités connues (OWASP
Dependency-Check)
• Ne jamais exposer les stack traces détaillées côté client en production
• Favoriser l'immutabilité des objets lorsque c'est possible, pour réduire les effets de bord