LES GÉNÉRIQUES
Les génériques en Java permettent
d'écrire des classes, des interfaces et public class Box<T> {
des méthodes plus flexibles et private T value;
réutilisables.
L'utilisation des génériques permet de public void set(T value) {
rendre le code plus lisible et plus sûr this.value = value;
notamment car il n'est plus nécessaire }
d'utiliser un cast et de définir une variable
intermédiaire. public T get() {
return value;
Les génériques peuvent être utilisés avec :
}
}
des types (classes, interfaces, etc.;)
des méthodes et des constructeurs Dans cet exemple, Box<T> est un type générique avec
T comme paramètre de type.
UTILISATION DES TYPES GÉNÉRIQUES
Les types génériques peuvent être utilisés pour définir des classes et des interfaces qui peuvent fonctionner avec
n'importe quel type.
public class Pair<K, V> { Les génériques peuvent également être utilisés avec des
private K key; méthodes et des constructeurs
private V value;
public class Util {
public static <T> void printArray(T[] array) {
public Pair(K key, V value) {
for (T element : array) {
this.key = key;
System.out.print(element + " ");
this.value = value;
}
}
System.out.println();
}
public K getKey() {
}
return key;
}
String[] strArray = {"Hello", "World"};
Integer[] intArray = {1, 2, 3};
public V getValue() {
return value; Util.printArray(strArray);
} Util.printArray(intArray);
} Instantiation
Pair<String, Integer> pair = new Pair<>("One", 1);
import java.util.ArrayList;
public class GenericsExample {
AVANTAGES DES GÉNÉRIQUES public static void main(String[] args) {
// Utilisation de Box avec différents types
Box<Integer> intBox = new Box<>();
intBox.set(10);
1. Sécurité du Type : Les génériques System.out.println("Integer Value: " + intBox.get());
permettent de détecter les erreurs
de type à la compilation plutôt qu'à Box<String> strBox = new Box<>();
l'exécution. strBox.set("Hello Generics");
2. Réutilisabilité du Code : Le même System.out.println("String Value: " + strBox.get());
code peut fonctionner avec
différents types. // Utilisation de Pair avec différents types
3. Élimination des Casts : Les Pair<String, Integer> pair = new Pair<>("Age", 30);
génériques éliminent la nécessité System.out.println("Key: " + pair.getKey() + ", Value: " + pair.getValue());
de faire des castings explicites, ce
// Utilisation de méthode générique
qui rend le code plus propre et plus
String[] strArray = {"A", "B", "C"};
lisible.
Integer[] intArray = {1, 2, 3};
Util.printArray(strArray);
Util.printArray(intArray);
Une classe comme ArrayList<E> est un type }
générique, qui possède un paramètre de type E.
}
LES CONVENTIONS DE NOMMAGE SUR LES NOMS DES TYPES
Le nom d'un type générique doit être un identifiant valide
en Java. Cependant par convention, on utilise une seule
lettre majuscule.
Dans le JDK, les noms des paramètres de types
couramment utilisés sont :
T : un type comme premier paramètre
E : un élément notamment dans les types de l'API Collection
N : un nombre
S, U V : un type comme paramètre supplémentaire
K : la clé d'une Map
V : la valeur d'une map
Le respect de cette convention permet de facilement
identifier l'utilisation d'un type générique dans le code
source.
source: https://www.jmdoudoux.fr/java/dej/chap-generique.htm
Les packages
C’est un moyen de regrouper les classes suivant
leur domaine spécifique
Pour déclarer un package dans une classe Java, on
utilise l'instruction package au début du fichier source,
avant toute autre déclaration.
Le mot clé package doit être la première instruction
dans un fichier source et il ne doit être présent qu'une
seule fois dans le fichier source (une classe ne peut pas
appartenir à plusieurs packages).
Deux classes entrent en collision lorsqu'elles portent le même nom
mais qu'elles sont définies dans des packages différents. Dans ce
cas, il faut qualifier explicitement le nom de la classe avec le nom
complet du package.
IMPORTATION DES PACKAGES
Pour utiliser une classe d'un autre package, vous devez l'importer en utilisant
l'instruction import.
import com.example.myapp.MyClass; Lorsque vous utilisez import nomPackage.*;, vous
importez toutes les classes du package spécifié.
public class Main {
Lorsque vous importez une classe spécifique avec import
public static void main(String[] args) {
nomPackage.nomClasse;, vous ne chargez que la classe
MyClass obj = new MyClass();
nécessaire,
// Utiliser l'objet
} Le package java.lang est importé automatiquement dans
} tous les programmes Java, il n'est donc pas nécessaire de
l'importer explicitement.
L'astérisque n'importe pas les sous-packages. Par exemple, il
n'est pas possible d'écrire import java.*.
LES EXCEPTIONS
GESTION DES EXCEPTIONS
En Java, les exceptions sont des erreurs qui
surviennent pendant l'exécution d'une application.
Elles diffèrent des erreurs de syntaxe, qui doivent
être corrigées avant de pouvoir compiler
l'application. La gestion des exceptions en Java se
fait principalement à l'aide des blocs try et catch.
Les erreurs de syntaxe doivent être corrigées avant la compilation.
Les exceptions doivent être gérées pour éviter que l'application ne
s'arrête pas de manière brusque.
GESTION DES EXCEPTIONS
Les blocs try et catch permettent de capturer et de traiter les exceptions pour
éviter l’interrumption brusque d’un programme en java.
try {
// Code pouvant provoquer une exception
} catch (TypeException e) {
// Code pour traiter l'exception
}
POUR MIEUX COMPRENDRE
Prenons l’exemple de Gestion d'une exception du type
NullPointerException
public class ExceptionExample {
public static void main(String[] args) {
try {
public class ExceptionExample {
String str = null;
public static void main(String[] args) { // Cela provoquera une NullPointerException
String str = null; int length = str.length();
} catch (NullPointerException e) {
// Cela provoquera une NullPointerException System.out.println("Une NullPointerException a été capturée.");
int length = str.length(); e.printStackTrace(); // Affiche la trace de la pile d'appels
} }
System.out.println("L'application continue de s'exécuter.");
} }
}
EXCEPTIONS MULTIPLES
public class MultipleCatchExample {
public static void main(String[] args) {
try {
String str = null;
int[] numbers = new int[5];
// Provoquera une NullPointerException
int length = str.length();
// Provoquera une ArrayIndexOutOfBoundsException
int num = numbers[10];
} catch (NullPointerException e) {
System.out.println("Une NullPointerException a été capturée.");
e.printStackTrace();
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Une ArrayIndexOutOfBoundsException a été capturée.");
e.printStackTrace();
}
System.out.println("L'application continue de s'exécuter.");
}
}
LE BLOC FINALLY
public class FinallyExample {
public static void main(String[] args) {
try {
String str = "Bonjour"; Le bloc finally contient du code
System.out.println(str.length()); qui s'exécute toujours, qu'une
} catch (Exception e) { exception soit levée ou non. Il est
System.out.println("Une exception a été souvent utilisé pour libérer des
capturée."); ressources telles que des fichiers
} finally { ou des connexions de base de
System.out.println("Le bloc finally est exécuté."); données.
}
System.out.println("L'application continue de
s'exécuter.");
}
}
// Définition de l'exception personnalisée
Exceptions Personnalisées en public class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
Java super(message);
}
}
public class AgeValidator {
public void validate(int age) throws InvalidAgeException {
Les exceptions personnalisées if (age < 18) {
throw new InvalidAgeException("L'âge doit avoir au moins 18 ans.");
sont des classes qui étendent
} else {
Exception ou l'une de ses sous- System.out.println("Âge valide : " + age);
classes. }
}
Cela permet de créer des
messages d'erreur plus significatifs public static void main(String[] args) {
AgeValidator validator = new AgeValidator();
et de mieux structurer la gestion
try {
des erreurs dans votre programme validator.validate(15); // Provoquera une InvalidAgeException
} catch (InvalidAgeException e) {
System.out.println("Exception capturée : " + e.getMessage());
e.printStackTrace();
}
}
}
DÉTAILS SUPPLÉMENTAIRES
Vous pouvez enrichir vos exceptions personnalisées en ajoutant des champs supplémentaires pour stocker plus
d'informations sur l'erreur.
public class DetailedAgeValidator {
// Définition de l'exception personnalisée avec des détails public void validate(int age) throws DetailedInvalidAgeException {
if (age < 18) {
supplémentaires
throw new DetailedInvalidAgeException("L'âge doit être au moins 18
public class DetailedInvalidAgeException extends Exception { ans.", age);
private int age; } else {
System.out.println("Âge valide : " + age);
}
public DetailedInvalidAgeException(String message, int age) { }
super(message);
this.age = age; public static void main(String[] args) {
DetailedAgeValidator validator = new DetailedAgeValidator();
}
try {
validator.validate(15); // Provoquera une DetailedInvalidAgeException
public int getAge() { } catch (DetailedInvalidAgeException e) {
return age; System.out.println("Exception capturée : " + e.getMessage());
System.out.println("Âge fourni : " + e.getAge());
} e.printStackTrace();
} }
}
}
ÉCHAUFFEMENT
INSTRUCTIONS
Objectif: Créer une interface générique
Container et une classe qui implémente cette
Utiliser une ArrayList pour stocker les objets de type Animal.
interface.
Ajouter des instances de chaque sous-classe à la collection :
1. Définissez une interface générique
Créer des objets pour chaque type d'animal et les ajouter à la
Container avec deux méthodes : add et get.
liste.
2. Créez une classe Box qui implémente Itérer sur la collection et afficher les détails de chaque animal
:
l'interface Container.
3. Écrivez un programme pour tester la classe Parcourir la liste des animaux et afficher leurs informations,
ainsi que les comportements spécifiques de chaque sous-
Box avec différents types de données.
classe.
INSTRUCTIONS
Objectif: Créer une interface générique Container et une classe qui implémente
cette interface.
1. Définissez une interface générique Container avec deux méthodes : add et get.
2. Créez une classe Box qui implémente l'interface Container.
3. Écrivez un programme pour tester la classe Box avec différents types de
données.
INSTRUCTIONS
Objectif: Écrire un programme qui demande à l'utilisateur de saisir deux entiers,
puis divise le premier par le second.
1. Demandez à l'utilisateur de saisir deux entiers.
2. Effectuez la division du premier entier par le second.
3. Utilisez un bloc try-catch pour gérer les exceptions ArithmeticException
(division par zéro).
4. Affichez un message approprié si une exception est capturée.
INSTRUCTIONS
Objectif: Créer une exception personnalisée InvalidScoreException
pour vérifier la validité d'un score.
1. Définissez une classe InvalidScoreException qui étend Exception.
2. Créez une méthode validateScore qui lève InvalidScoreException si
le score est en dehors de l'intervalle 0-100.
3. Utilisez un bloc try-catch pour gérer l'exception et afficher un
message approprié.
INSTRUCTIONS
Objectif
L'objectif de ce projet est de développer une application console en Java pour
les paris sur les matchs de football. L'application doit vérifier que l'utilisateur est
majeur (au moins 18 ans) et permettre à l'utilisateur de prédire le score d'un
match. Les scores prédits doivent être des valeurs positives.
L'utilisateur doit entrer son âge.
Si l'utilisateur a moins de 18 ans, l'application affiche un message d'erreur et
se termine.
Si l'utilisateur a 18 ans ou plus, l'application passe à l'étape suivante.
L'utilisateur doit entrer les scores prédits pour les deux équipes.
Si l'un des scores est négatif ou nul, l'application affiche un message d'erreur
et demande de réentrer les scores.
Affichage des résultats:
L'application doit afficher les scores prédits par l'utilisateur.