Cheatsheet — Java 8 → Java 21
Résumé des apports majeurs par version avec exemples avant/après et problématiques résolues.
Java 8 (2014)
Lambdas & Streams
// Avant
List<String> result = new ArrayList<>();
for (String n : noms) {
if (n.startsWith("C")) result.add(n);
}
// Après
List<String> result = noms.stream()
.filter(n -> n.startsWith("C"))
.toList();
Problématique résolue : rendre le code plus concis, déclaratif et parallélisable.
Optional
// Avant
if (user != null) {
sendEmail(user);
}
// Après
Optional.ofNullable(user).ifPresent(u -> sendEmail(u));
Problématique résolue : réduire les NullPointerException.
API Date/Time (java.time)
// Avant
Date d = new Date();
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, 7);
// Après
LocalDate now = LocalDate.now();
LocalDate nextWeek = now.plusWeeks(1);
Problématique résolue : remplacer une API peu intuitive par une API claire et immuable.
Java 9 (2017)
Modules (Jigsaw)
// Avant : pas de modularité stricte
// Tout était accessible dans le classpath.
// Après
module com.monapp {
requires java.sql;
exports com.monapp.service;
}
Problématique résolue : meilleure encapsulation et modularité.
Collections immuables
// Avant
List<String> fixed = Collections.unmodifiableList(Arrays.asList("a","b","c"));
// Après
List<String> fixed = List.of("a","b","c");
Problématique résolue : construction simple et sûre de collections immuables.
Java 10 (2018)
var
// Avant
Map<String, List<Integer>> map = new HashMap<>();
// Après
var map = new HashMap<String, List<Integer>>();
Problématique résolue : réduire le bruit syntaxique.
Java 11 (2018 – LTS)
HTTP Client
// Avant
URL url = new URL("https://api");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// Après
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder().uri(URI.create("https://api")).build();
HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString());
Problématique résolue : API moderne et support de HTTP/2.
String API
// Avant
" hi ".trim(); // mais supprime seulement les espaces
// Après
" hi ".strip(); // supprime tous les blancs Unicode
Problématique résolue : utilitaires String plus puissants.
Java 12 (2019)
Switch expression (preview)
// Avant
String type;
switch(day) {
case 1: case 7: type = "Weekend"; break;
default: type = "Weekday";
}
// Après
String type = switch(day) {
case 1, 7 -> "Weekend";
default -> "Weekday";
};
Problématique résolue : switch concis et sans erreurs de break.
Java 13 (2019)
Text blocks (preview)
// Avant
String json = "{\n \"name\": \"Alice\"\n}";
// Après
String json = """
{
"name": "Alice"
}
""";
Problématique résolue : littéraux multilignes sans concaténation.
Java 14 (2020)
Records
// Avant
class Person {
private final String name;
private final int age;
Person(String n, int a) { this.name=n; this.age=a; }
public String name() { return name; }
public int age() { return age; }
}
// Après
record Person(String name, int age) {}
Problématique résolue : suppression du boilerplate.
Pattern matching instanceof
// Avant
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
// Après
if (obj instanceof String s) {
System.out.println(s.length());
}
Problématique résolue : éviter les casts répétitifs.
Java 15 (2020)
Sealed classes
// Avant : hiérarchie non contrôlée
interface Shape {}
class Circle implements Shape {}
class Square implements Shape {}
// Après
sealed interface Shape permits Circle, Square {}
final class Circle implements Shape {}
final class Square implements Shape {}
Problématique résolue : contrôle des sous-types autorisés.
Java 16 (2021)
Records et pattern matching stabilisés ➡️ Production-ready, mêmes exemples que Java 14.
jpackage
# Avant : outils tiers (Launch4j, InnoSetup...)
# Après :
jpackage --name MonApp --input out/ --main-jar monapp.jar
Problématique résolue : création d’installateurs natifs.
Java 17 (2021 – LTS)
Pattern matching switch
// Avant
if (o instanceof String) return "String";
else if (o instanceof Integer) return "int";
// Après
return switch(o) {
case String s -> "String";
case Integer i -> "int";
default -> "other";
};
Problématique résolue : switch exhaustif et typé.
Java 18 (2022)
Mini serveur web
# Avant : dépendance externe (Jetty, Tomcat...)
# Après :
jwebserver --port 8080 --directory .
Problématique résolue : serveur léger intégré pour dev/test.
Java 19 (2022)
Virtual Threads (preview)
// Avant : threads classiques lourds
new Thread(() -> System.out.println("Hi")).start();
// Après
Thread.startVirtualThread(() -> System.out.println("Hi"));
Problématique résolue : millions de threads possibles.
Java 20 (2023)
Record patterns (preview)
// Avant
if (p instanceof Point) {
Point pt = (Point) p;
System.out.println(pt.x()+", "+pt.y());
}
// Après
if (p instanceof Point(int x, int y)) {
System.out.println(x+", "+y);
}
Problématique résolue : destructuration claire.
Java 21 (2023 – LTS)
Virtual Threads (finalisé)
// Avant
ExecutorService pool = Executors.newFixedThreadPool(10);
// Après
try (var exec = Executors.newVirtualThreadPerTaskExecutor()) {
exec.submit(() -> Thread.sleep(1000));
}
Problématique résolue : simplifier la concurrence massivement.
String Templates (preview)
// Avant
String msg = "Name: " + name + ", Age: " + age;
// Après
String msg = STR."Name: \{name}, Age: \{age}";
Problématique résolue : interpolation lisible et sûre.
Record patterns + switch ➡️ mêmes améliorations que Java 20, finalisées.
Synthèse
- Java 8 : lambdas, streams, date/time moderne.
- Java 9–11 : modularité, API modernes (HTTP client).
- Java 12–16 : switch expressions, records, text blocks.
- Java 17 (LTS) : pattern matching, sealed classes.
- Java 19–21 : virtual threads, record patterns, string templates — modernisation de la concurrence et expressivité du langage.