Examen Java – Difficile
2025
Instructions :
— Indiquez clairement vos nom, prénom et groupe.
— Les réponses doivent être rédigées de façon claire.
— Justifiez vos réponses quand c’est nécessaire.
— Tout document interdit.
Exercice 1 : Questions de cours (4 pts)
1. Expliquez ce qu’est l’encapsulation en Java et pourquoi elle est importante. Donnez
un exemple où l’absence d’encapsulation pose problème.
2. Définissez l’héritage. Montrez avec un diagramme UML simple l’héritage entre trois
classes.
3. Qu’est-ce que la surcharge (overloading) en Java ? Distinguez surcharge de redéfini-
tion (overriding).
4. Que signifie le mot-clé final appliqué à une classe, à une méthode, à une variable ?
Donnez des exemples.
5. Donnez la différence entre une classe abstraite et une interface.
1
Exercice 2 : Correction d’un code erroné (4 pts)
Le code ci-dessous contient plusieurs erreurs (fichiers, exceptions, génériques, etc.).
Relevez et corrigez chaque erreur :
1 import java . util .*;
2 public class Main {
3 public static void main ( String [] args ) {
4 List < String > valeurs = new ArrayList () ;
5 valeurs . add (42) ;
6 valeurs . add ( " Java " ) ;
7 System . out . println ( valeurs . get (2) ) ;
8
9 int [] t = {1 , 2 , 3};
10 for ( int i = 0; i <= t . length ; i ++)
11 System . out . println ( t [ i ]) ;
12
13 try {
14 FileInputStream fis = new FileInputStream ( " donnees . txt "
);
15 while ( fis . read () != -1)
16 System . out . print (( char ) fis . read () ) ;
17 fis . close () ;
18 } catch ( Exception e ) {
19 System . out . println ( " Erreur IO " ) ;
20 }
21 }
22 }
Exercice 3 : Exécution d’un code complexe (4 pts)
Voici un code Java. Expliquez ce qu’il affiche, ligne par ligne. Justifiez votre raisonne-
ment.
1 LinkedList < Integer > liste = new LinkedList < >() ;
2 liste . add (1) ; liste . add (3) ; liste . add (5) ; liste . add (7) ;
3 for ( int i = 0; i < liste . size () ; i ++) {
4 if ( liste . get ( i ) % 2 != 0) {
5 liste . remove ( i ) ;
6 }
7 }
8 System . out . println ( liste ) ;
a) Quel est le résultat affiché ? Expliquez pas à pas.
b) Pourquoi ce code peut poser problème ? Comment le corriger pour supprimer tous
les impairs ?
2
Exercice 4 : Collections avancées (4 pts)
a) (ArrayList) Écrivez le code Java pour :
— Créer une ArrayList de chaînes de caractères.
— Ajouter : "a", "b", "c", "d", "e"
— Remplacer "c" par "z"
— Supprimer le dernier élément
— Parcourir la liste avec un Iterator et afficher chaque élément
b) (LinkedList) Écrivez le code Java pour :
— Créer une LinkedList d’entiers
— Ajouter : 10, 20, 30
— Ajouter 5 au début, 40 à la fin
— Supprimer le dernier élément
— Parcourir la liste avec une boucle for-each et afficher chaque élément
Exercice 5 : Fonctions Lambda (2 pts)
a) Déclarez une interface fonctionnelle Opération avec une méthode int calcul(int a,
int b), puis créez deux lambdas pour l’addition et la multiplication.
b) Donnez un exemple d’utilisation d’une interface fonctionnelle standard (Predicate ou
Function) pour filtrer une liste d’entiers et n’afficher que les pairs.
Exercice 6 : Swing (2 pts)
Créez une interface graphique avec trois champs de texte : nom d’utilisateur, mot de
passe et email, et un bouton « Valider ». Quand on clique sur le bouton, vérifiez que les
champs ne sont pas vides : si oui, affichez « Inscription réussie », sinon affichez une boîte
d’erreur.
3
CORRECTION DÉTAILLÉE
Exercice 1 : Questions de cours
1. Encapsulation : L’encapsulation consiste à cacher les données internes d’une classe
(attributs) pour qu’elles ne soient pas accessibles directement de l’extérieur. On
utilise le mot-clé private pour les attributs et on fournit des méthodes publiques
get...() (pour lire la valeur) et set...() (pour modifier la valeur). Cela protège
les données contre les modifications inattendues et rend le code plus sûr et facile à
maintenir.
Exemple sans encapsulation :
1 class Compte {
2 public double solde ;
3 }
4 Compte c = new Compte () ;
5 c . solde = -10000; // Erreur ! solde negatif permis car public
Ici, n’importe qui peut mettre n’importe quelle valeur à solde, même négative.
Avec encapsulation :
1 class Compte {
2 private double solde ;
3 public double getSolde () { return solde ; }
4 public void setSolde ( double s ) {
5 if ( s >= 0) this . solde = s ;
6 }
7 }
Ici, on ne peut pas mettre un solde négatif car le setter vérifie la valeur.
2. Héritage et schéma UML : L’héritage permet à une classe fille (sous-classe)
de reprendre le code d’une classe mère (super-classe) et de le compléter ou de le
modifier. Cela favorise la réutilisation du code et la spécialisation.
Exemple UML :
Animal
Chien BergerAllemand
+ nom : String → →
+ crier() : void + crier() : void
+ crier() : void
En code Java :
1 class Animal { String nom ; void crier () {} }
2 class Chien extends Animal { void crier () { System . out . println
( " Ouaf " ) ; } }
3 class BergerAllemand extends Chien { void crier () { System . out
. println ( " Grrr ! " ) ; } }
4
3. Surcharge (overloading) vs Redéfinition (overriding) :
— Surcharge (overloading) : Définir plusieurs méthodes avec le même nom
dans la même classe, mais des signatures différentes (nombre ou type des pa-
ramètres).
— Redéfinition (overriding) : Dans une classe fille, on redéfinit une méthode
de la classe mère pour en modifier le comportement.
Exemple :
1 class MaClasse {
2 void affiche () { System . out . println ( " Sans argument " ) ; }
3 void affiche ( String s ) { System . out . println ( s ) ; } //
Surcharge
4 }
5 class MaClasseFille extends MaClasse {
6 @Override
7 void affiche () { System . out . println ( " R e d f i n i " ) ; } //
Redefinition
8 }
4. final (variable, méthode, classe) :
— final sur une variable : elle ne peut pas changer de valeur après initialisation.
— final sur une méthode : elle ne peut pas être redéfinie dans une sous-classe.
— final sur une classe : on ne peut pas hériter de cette classe.
Exemples :
1 final int x = 10; // x ne peut pas tre modifi
2 final class Util {} // On ne peut pas faire class Y extends
Util
3 class A { final void f () {} } // f () ne peut etre redefinie
5. Différence classe abstraite vs interface :
— Classe abstraite : Peut contenir des méthodes abstraites (sans corps) ET des
méthodes concrètes (avec corps), des attributs. Sert de modèle de base.
— Interface : Ne contient que des méthodes abstraites (avant Java 8), pas d’at-
tributs (sauf constantes), pas de constructeurs. Sert de contrat.
Exemple :
1 abstract class Animal { abstract void crier () ; void dormir ()
{} }
2 interface Volant { void voler () ; }
3 class Oiseau extends Animal implements Volant { void crier ()
{}; public void voler () {} }
5
Exercice 2 : Correction du code
Erreur 1 : List<String> valeurs = new ArrayList();
Problème : Manque le paramètre de type générique à droite, mettre new ArrayList<String>()
ou new ArrayList<>() (Java 7+).
Erreur 2 : valeurs.add(42);
Problème : La liste attend des String, ici on ajoute un entier. Il faut écrire valeurs.add("42");
Erreur 3 : System.out.println(valeurs.get(2));
Problème : Il n’y a que deux éléments dans la liste (indices 0 et 1), donc get(2) provoque
une erreur d’index hors limites. Il faut utiliser get(1).
Erreur 4 : for (int i = 0; i <= t.length; i++)
Problème : t.length vaut 3, donc quand i == 3, on aura t[3], qui n’existe pas (indices
0, 1, 2). Il faut i < t.length.
Erreur 5 : while(fis.read() != -1) System.out.print((char) fis.read());
Problème : On lit deux fois à chaque tour (une fois dans la condition, une fois dans
le print), ce qui saute des caractères. Il faut stocker le résultat de fis.read() dans une
variable.
Erreur 6 : FileInputStream doit être importé (import java.io.*;).
Code corrigé :
1 import java . util .*;
2 import java . io .*;
3
4 public class Main {
5 public static void main ( String [] args ) {
6 List < String > valeurs = new ArrayList < >() ;
7 valeurs . add ( " 42 " ) ;
8 valeurs . add ( " Java " ) ;
9 System . out . println ( valeurs . get (1) ) ;
10
11 int [] t = {1 , 2 , 3};
12 for ( int i = 0; i < t . length ; i ++)
13 System . out . println ( t [ i ]) ;
14
15 try {
16 FileInputStream fis = new FileInputStream ( " donnees . txt "
);
17 int b ;
18 while (( b = fis . read () ) != -1)
19 System . out . print (( char ) b ) ;
20 fis . close () ;
21 } catch ( Exception e ) {
22 System . out . println ( " Erreur IO " ) ;
23 }
24 }
25 }
6
Explications :
— On précise le type de la liste (générique).
— On n’ajoute que des chaînes dans la liste.
— L’accès à la liste est fait sur des indices existants.
— La boucle sur le tableau ne dépasse pas la taille.
— On lit les fichiers octet par octet, sans rater des caractères.
Exercice 3 : Exécution d’un code complexe
Code :
1 LinkedList < Integer > liste = new LinkedList < >() ;
2 liste . add (1) ; liste . add (3) ; liste . add (5) ; liste . add (7) ;
3 for ( int i = 0; i < liste . size () ; i ++) {
4 if ( liste . get ( i ) % 2 != 0) {
5 liste . remove ( i ) ;
6 }
7 }
8 System . out . println ( liste ) ;
Explication détaillée :
Initialisation : liste = [1, 3, 5, 7]
— i = 0 : liste.get(0) = 1, impair → on retire 1
La liste devient [3, 5, 7], i reste à 0, la boucle continue.
— i = 1 : liste.get(1) = 5, impair → on retire 5
La liste devient [3, 7], i est à 1 (car après un remove, les éléments sont décalés). La
boucle continue.
— i = 2 : la taille de la liste est 2, donc la boucle s’arrête.
Affichage final : [3, 7]
Mais le but était de retirer tous les impairs : ici certains ne sont pas retirés
à cause du décalage des indices après un remove(i).
Pour supprimer correctement tous les impairs :
— Méthode 1 : Parcourir la liste à l’envers :
1 for ( int i = liste . size () - 1; i >= 0; i - -) {
2 if ( liste . get ( i ) % 2 != 0) {
3 liste . remove ( i ) ;
4 }
5 }
— Méthode 2 : Utiliser un Iterator :
1 Iterator < Integer > it = liste . iterator () ;
2 while ( it . hasNext () ) {
3 if ( it . next () % 2 != 0) it . remove () ;
4 }
Après suppression correcte, la liste sera vide.
7
Exercice 4 : Collections avancées
a) ArrayList de chaînes :
1 // Creer ArrayList de chaines
2 ArrayList < String > liste = new ArrayList < >() ;
3 liste . add ( " a " ) ;
4 liste . add ( " b " ) ;
5 liste . add ( " c " ) ;
6 liste . add ( " d " ) ;
7 liste . add ( " e " ) ;
8
9 // Remplacer " c " par " z "
10 int idx = liste . indexOf ( " c " ) ;
11 if ( idx != -1) liste . set ( idx , " z " ) ;
12
13 // Supprimer le dernier element
14 liste . remove ( liste . size () - 1) ;
15
16 // Parcourir la liste avec un Iterator
17 Iterator < String > it = liste . iterator () ;
18 while ( it . hasNext () )
19 System . out . println ( it . next () ) ;
Explications :
— indexOf cherche l’index d’un élément.
— set modifie la valeur à un index donné.
— remove(liste.size()-1) supprime le dernier élément (ici "e").
— Un Iterator permet de parcourir et d’enlever des éléments en toute sécurité.
b) LinkedList d’entiers :
1 // Creer LinkedList d ’ entiers
2 LinkedList < Integer > l = new LinkedList < >() ;
3 l . add (10) ; l . add (20) ; l . add (30) ;
4
5 // Ajouter 5 au debut
6 l . addFirst (5) ;
7 // Ajouter 40 a la fin
8 l . addLast (40) ;
9 // Supprimer le dernier element
10 l . removeLast () ;
11
12 // Afficher chaque element avec for - each
13 for ( Integer val : l )
14 System . out . println ( val ) ;
Explications :
— addFirst, addLast, removeLast sont spécifiques à LinkedList.
— La boucle for-each affiche chaque entier de la liste.
8
Exercice 5 : Fonctions Lambda
a) Interface Opération, lambdas addition/multiplication :
1 @FunctionalInterface
2 interface Operation {
3 int calcul ( int a , int b ) ;
4 }
5 Operation add = (a , b ) -> a + b ;
6 Operation mul = (a , b ) -> a * b ;
7
8 System . out . println ( add . calcul (3 , 4) ) ; // 7
9 System . out . println ( mul . calcul (3 , 4) ) ; // 12
Explications :
— L’annotation @FunctionalInterface indique que l’interface a une seule méthode
abstraite.
— Les expressions (a, b) -> a + b et (a, b) -> a * b sont des fonctions anonymes
(lambdas).
— add.calcul(3,4) effectue l’addition, mul.calcul(3,4) la multiplication.
b) Utiliser Predicate pour filtrer les pairs :
1 import java . util .*;
2 import java . util . function .*;
3
4 List < Integer > nombres = Arrays . asList (2 , 5 , 8 , 11 , 14) ;
5
6 Predicate < Integer > estPair = n -> n % 2 == 0;
7
8 for ( Integer n : nombres ) {
9 if ( estPair . test ( n ) )
10 System . out . println ( n + " est pair " ) ;
11 }
Explications :
— Predicate<Integer> prend un entier et retourne un booléen.
— On applique test(n) à chaque nombre de la liste.
— Seuls les nombres pairs sont affichés.
Exercice 6 : Swing
Objectif : Créer une interface graphique avec trois champs (nom d’utilisateur, mot
de passe, email), un bouton, et vérifier que tous les champs sont remplis.
Étapes :
1. Créer la fenêtre principale (JFrame).
2. Créer trois champs de texte (JTextField, JPasswordField).
3. Créer un bouton JButton.
4. Ajouter un gestionnaire d’événement au bouton.
5. Vérifier que les champs ne sont pas vides, sinon afficher une erreur.
9
Exemple de code détaillé :
1 import javax . swing .*;
2 import java . awt .*;
3 import java . awt . event .*;
4
5 public class Inscription {
6 public static void main ( String [] args ) {
7 JFrame fen = new JFrame ( " Inscription " ) ;
8 fen . setSize (350 , 200) ;
9 fen . s etDe faul tClo seO pera tion ( JFrame . EXIT_ON_CLOSE ) ;
10 fen . setLocationRelativeTo ( null ) ;
11
12 JPanel panel = new JPanel ( new GridLayout (4 ,2) ) ;
13 JLabel lblUser = new JLabel ( " Nom d ’ utilisateur : " ) ;
14 JTextField txtUser = new JTextField () ;
15 JLabel lblPwd = new JLabel ( " Mot de passe : " ) ;
16 JPasswordField txtPwd = new JPasswordField () ;
17 JLabel lblMail = new JLabel ( " Email : " ) ;
18 JTextField txtMail = new JTextField () ;
19 JButton btn = new JButton ( " Valider " ) ;
20
21 panel . add ( lblUser ) ; panel . add ( txtUser ) ;
22 panel . add ( lblPwd ) ; panel . add ( txtPwd ) ;
23 panel . add ( lblMail ) ; panel . add ( txtMail ) ;
24 panel . add ( new JLabel () ) ; panel . add ( btn ) ;
25
26 fen . add ( panel ) ;
27
28 btn . addActionListener ( new ActionListener () {
29 public void actionPerformed ( ActionEvent e ) {
30 String user = txtUser . getText () ;
31 String pwd = new String ( txtPwd . getPassword () ) ;
32 String mail = txtMail . getText () ;
33 if ( user . isEmpty () || pwd . isEmpty () || mail . isEmpty
() ) {
34 JOptionPane . showMessageDialog ( fen , " Tous les
champs sont obligatoires ! " , " Erreur " ,
JOptionPane . ERROR_MESSAGE ) ;
35 } else {
36 JOptionPane . showMessageDialog ( fen , " Inscription
r u s s i e !");
37 }
38 }
39 }) ;
40
41 fen . setVisible ( true ) ;
42 }
43 }
10
Explications :
— JPanel avec un GridLayout pour aligner les éléments.
— JTextField pour le login et l’email, JPasswordField pour le mot de passe.
— On vérifie si un champ est vide avec isEmpty().
— Si un champ est vide, on affiche une erreur (JOptionPane.ERROR_MESSAGE).
— Sinon, message de succès.
11