Imprimer
Catégorie : R3.04 - Concept. et prog, objet avancée
Affichages : 8511

1°/ Préambule & tutoriel sur les exceptions

1.1°/ Principes

Exemple :

FileReader f = null;
try {
    f = new FileReader("toto.txt"); // si toto.txt n'existe pas, un objet FileNotFoundException est lancé par FileReader()
    ...
}
catch(IOException e) { ... }

 

Exemple :

String s1 = null;
String s2 = "salut";
System.out.println(s1.contains("a")); // génère NullPointerException car s1 = null
System.out.println(Integer.parseInt(s2)); // génère NumberFormatException

 

1.2°/ Syntaxe

1.2.1°/ capture des exceptions.

Exemple :

ObjectInputStream ois = null;
Double d = null;
try {
    ois = new ObjectInputStream(new FileInputStream("toto.txt"));
    d = (Double)(ois.readObject());
    System.out.println("lu : "+d);
}
catch(ClassNotFoundException e) {
    System.out.println("pb de classe : "+e.getMessage());
}
catch(IOException e) {
    System.out.println("pb accès fichier : "+e.getMessage());
}
System.out.println("après try/catch");
...

Principe :

 ATTENTION :

1.2.2°/ Ecrire des méthodes qui génèrent des exceptions

Exemple :

class Population {
    List<Humain> pop;
    ...
    public void setHumanAge(int index, int age) throws IndexOutOfBoundsException, PropertyVetoException {

        if (index <0 || index >= pop.size()) throw new IndexOutOfBoundsException();
        if (age <0 || age > 150) throw new PropertyVetoException();
        ...
    }
    ...
}

Remarques :

 

1.3°/ Propagation des exceptions

1.3.1°/ Propagation implicite (= automatique)

1.3.2°/ Propagation explicite (= choisie par le programmeur)

 

1.4°/ Étendre les classes d'exception

Exemple :

class PopulationException extends Exception {
    public PopulationException() {
        super("This is a population exception");
    }
}
  • Si besoin, on ajoute des attributs, initialisés via le constructeur, qui vont notamment être utiles pour redéfinir getMessage()

Exemple :

class PopulationException extends Exception {
    Population pop;
    public PopulationException(Population pop) {
        super("This is a population exception");
        this.pop = pop;
    }
    public String getMessage() {
        if (pop.taille() == 0) return "population is empty";
        if (pop.onlyMen() || pop.onlyWomen()) return "population cannot grow";
    }
}

2°/ Rencontre impossible = exception

class BreedingForbiddenException extends Exception {
 
    protected Humain[] source;
 
    public BreedingForbiddenException(Humain h1, Humain h2) {
	super("naissance impossible : "+h1.getNom()+" et "+h2.getNom()+" sont de meme sexe");
	source = new Humain[2];
	source[0] = h1;
	source[1] = h2;
    }
 
    public Humain[] getHumain() {
	return source;
    }     
}
 

 

3°/ Rencontre non productive = exception

 

  • Il est également possible que les deux humains soient de sexes opposés mais les conditions (sur le poids, age, ...) ne sont pas respectées ou bien le tirage aléatoire sur la fertilité a été négatif.
  • Dans ces deux cas, il n'y a pas de nouvel humain et la valeur renvoyée est de nouveau null.
  • Pour éviter ce problème, on va :
    • générer une BreedingForbiddenException quand les conditions sur le poids, age, ... ne sont pas respectées
    • générer une NoBreedingException quand le tirage sur la fertilité ou bien batifolage est négatif.
  • Pour le deuxième cas, créez une classe NoBreedingException qui a comme attribut un Humain représentant la source de l'erreur et dont le message d'erreur est du type : "rencontre improductive : toto n'est pas fertile" ou bien "rencontre infertile : tutu veut batifoler"
  • Dans BreedingForbiddenException, modifiez le code pour avoir un message différent selon le cas (NB: cela impose de redéfinir la méthode getMessage()  ) :
    • même sexe : le message est le même que dans l'exercice 2
    • conditions d'âge et/ou poids non respectées : message donnant les conditions non conformes. Par exemple :  "naissance impossible : toto est trop jeune, tutu est trop vieille, tutu est trop gros"
  • Modifiez Humain, Homme, Femme et le moteur de jeu pour utiliser les deux classes d'exception.

 

4°/ Une super-classe pour les exceptions de rencontre.

  • Créez le fichier MeetingException.java à partir du code suivant :
class MeetingException extends Exception {
 
    protected Humain[] source;
 
    public MeetingException(Humain h1, Humain h2) {
	super("problème de rencontre");
	source = new Humain[2];
	source[0] = h1;
	source[1] = h2;
    }
 
    public Humain[] getHumain() {
	return source;
    }
}
  • Modifiez les deux classes d'exception pour qu'elles héritent de cette classe.

 

5°/ la propagation des exceptions

  • Modifiez la classe Population en ajoutant une méthode rencontre :
public Humain rencontre(int index1, int index2) {
   Humain h1 = getHumain(index1);
   Humain h2 = getHumain(index2);
   return h1.rencontre(h2);     
}
  • Modifiez le moteur de jeu pour appeler cette méthode pour faire lors des rencontres, au lieu de le faire directement.
  • On remarque que la méthode ne fait pas de try/catch. Or, elle génère potentiellement des exceptions. Le compilation va donc échouer.
  • Modifiez le code ci-dessus pour que la méthode propage les exceptions explicitement au moteur de jeu.