Partage
  • Partager sur Facebook
  • Partager sur Twitter

Les exceptions

    28 mai 2009 à 19:28:06

    Bonjour tlm,
    regardez le code suivant du tuto de java su sdz:
    la classe "main":
    Ville2 v = null;
    		try {                   
    			v = new Ville2("Re", -12000, "France");           
    		}
    		//Gestion de l'exception sur le nombre d'habitants
    		catch (NombreHabitantException e) {
    			e.printStackTrace();
    			v = new Ville2();
    		}
    		//Gestion de l'exception sur le nom de la ville
    		catch(NomVilleException e2){
    			System.out.println(e2.getMessage());
    			v = new Ville2();
    		}
    
    		System.out.println(v.toString());
    


    La classe "Ville2":
    public class Ville2 {
    	
    
    	protected String nomVille;
    
    	protected String nomPays;
    
    	protected int nbreHabitant;
    
    	protected char categorie;
    
    
    	public static int nbreInstance = 0;
    
    	private static int nbreInstanceBis = 0;// Variable privée qui comptera aussi les instances
    
    
    	//Constructeur par défaut :	 
    	public Ville2(){
    		nbreInstance++;
    		nbreInstanceBis++;
    		nomVille = "Inconnu";
    		nomPays = "Inconnu";
    		nbreHabitant = 0;
    		this.setCategorie();
    
    	}
    
    	//Constructeur d'initialisation de "Ville" avec paramètres:	 
    	public Ville2(String pNom, int pNbre, String pPays) throws  NombreHabitantException, NomVilleException
    	  {  //Vous remarquez que les différentes erreurs dans l'instruction throws sont séparées par une virgule
    	          if(pNbre < 0)
    	                  throw new NombreHabitantException(pNbre);
    	          
    	          if(pNom.length() < 3)
    	                  throw new NomVilleException("le nom de la ville est inférieur à 3 caractères ! nom = " + pNom);
    	          else
    	          {
    	                  nbreInstance++;  
    	                  nbreInstanceBis++;
    	                  
    	                  nomVille = pNom;
    	                  nomPays = pPays;
    	                  nbreHabitant = pNbre;
    	                  this.setCategorie();
    	          }
    	          
    	  }
            
    
    	//*****************************************************************************************
    	//                                    ACCESSEURS
    	//*****************************************************************************************
    
    
    	public String getNom()    //Retourne le nom de la ville
    	{
    		return nomVille;
    	}
    
    
    	public String getNomPays() //Retourne le nom du pays
    	{
    		return nomPays;
    	}
    
    
    	public int getNombreHabitant() // Retourne le nombre d'habitants
    	{
    		return nbreHabitant;
    	}
    
    	public char getCategorie() //Retourne la catégorie de la ville
    	{
    		return categorie;
    	}
    
    	public static int getNombreInstanceBis()//l'accesseur de notre variable de classe déclarée privée est aussi 
    	//déclaré static, et ceci est une règle
    	{
    		return nbreInstanceBis;
    	}
    
    	//NB:
    	//Toutes les méthodes de classes n'utilisant que des variables de classes doivent être déclarées static ! On 
    	//les appelle des méthodes de classes car elles sont globales à toutes vos instances !
    	//Par contre ceci n'est plus vrai si une méthode utilise des variables d'instances et des variables de 
    	//classes...
    
    	//*****************************************************************************************
    	//                                    MUTATEURS
    	//*****************************************************************************************
    
    	public void setNom(String pNom)   //Définit le nom de la ville
    	{
    		nomVille = pNom;
    	}
    
    
    	public void setNomPays(String pPays)  //Définit le nom du pays
    	{
    		nomPays = pPays;
    	}
    
    	public void setNombreHabitant(int nbre)  // Définit le nombre d'habitants
    	{
    		nbreHabitant = nbre;
    		this.setCategorie();// à la place du mutateur de catégorie
    	}
    
    	//	//*****************************************************************************************
    	//                                    METHODES DE CLASSE
    	//	//*****************************************************************************************
    
    	//Il faut différencier :
    	//
    	//	    * les constructeurs => méthodes servant à créer des objets
    	//	    * les accesseurs => méthodes servant à accéder aux données de nos objets
    	//	    * et les méthodes de classe => méthodes servant à la gestion de nos objets.
    
    
    
    
    
    	  protected void setCategorie() {
    	 
    	      
    	      int bornesSuperieures[] = {0, 1000, 10000, 100000, 500000, 1000000, 5000000, 10000000};
    	        char categories[] = {'?', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
    
    	        int i = 0;
    	        while (i < bornesSuperieures.length && this.nbreHabitant > bornesSuperieures[i])
    	                i++;
    
    	        this.categorie = categories[i];
    
    	 
    	  }
    	 
    
    	  public String decrisToi(){
    	      return "\t"+this.nomVille+" est une ville de "+this.nomPays+", elle comporte : "+this.nbreHabitant+
    	              " => elle est donc de catégorie : "+this.categorie;
    	  }
    	  
    	  public String toString(){
    		  return "\t"+this.nomVille+" est une ville de "+this.nomPays+", elle comporte : "+this.nbreHabitant+
    		        " => elle est donc de catégorie : "+this.categorie;
    		 }
    
    	 
    
    	  public String comparer(Ville2 v1){
    	      String str = new String();
    	     
    	      if (v1.getNombreHabitant() > this.nbreHabitant)
    	          str = v1.getNom()+" est une ville plus peuplée que "+this.nomVille;
    	     
    	      else
    	          str = this.nomVille+" est une ville plus peuplée que "+v1.getNom();
    	     
    	      return str;
    	     
    	  }
    
    }
    


    La classe "NomVilleException":
    public class NomVilleException extends Exception {
    
    	public NomVilleException(String message){
    		super(message);//Pour afficher notre message d'erreur en utilisant la méthode getMessage().
    
    	}
    }
    


    La classe "NombreHabitantException":
    public class NombreHabitantException extends Exception {
    
    
    	public NombreHabitantException(){
    		System.out.println("Vous essayez d'instancier une classe Ville avec un nombre d'habitants négatif !");
    	}
    	 //Constructeur d'initialisation de la classe " NombreHabitantException"
    	public NombreHabitantException(int nbre)
    	{
    	    System.out.println("Instanciation avec un nombre d'habitants négatif");
    	    System.out.println("\t => " + nbre);
    	}
    
    }
    


    Lorsque j'exécute le programme j'ai le résultat suivant:
    Instanciation avec un nombre d'habitants négatif
    => -12000
    Inconnu est une ville de Inconnu, elle comporte : 0 => elle est donc de catégorie : ?
    f_LesExceptions.NombreHabitantException
    at f_LesExceptions.Ville2.<init>(Ville2.java:35)
    at f_LesExceptions.D_LaGestionDePlusieursExceptions.main(D_LaGestionDePlusieursExceptions.java:148)

    Donc vous voyez bien qu'il n y a que l'exception "NombreHabitantException" qui a été levée, et pas l'exception "NomVilleException " pourtant le nom de la ville contient bien un nombre inferieur à 3:"RE" (voir le constructeur d'initialisation de Ville2).
    Ma question est: pourquoi?
    • Partager sur Facebook
    • Partager sur Twitter
      28 mai 2009 à 19:41:28

      Le programme s'arrête à la *première* exception levée, sauf si elle est catchée. Ensuite, le programme reprend *après* le catch (Ou s'arrête s'il n'y a pas de catch).
      • Partager sur Facebook
      • Partager sur Twitter
        28 mai 2009 à 20:02:42

        Merci Veldryn, tu veux bien revoir la classe main:
        Ville2 v = null;
        		try {                   
        			v = new Ville2("Re", -12000, "France");           
        		}
        		//Gestion de l'exception sur le nombre d'habitants
        		catch (NombreHabitantException e) {
        			e.printStackTrace();
        			v = new Ville2();
        		}
        		//Gestion de l'exception sur le nom de la ville
        		catch(NomVilleException e2){
        			System.out.println(e2.getMessage());
        			v = new Ville2();
        		}
        
        		System.out.println(v.toString());
        

        l'exception "NomVilleException " et bien catchée mais elle n'est pourtant pas traitée, so where is the problème?
        • Partager sur Facebook
        • Partager sur Twitter
          28 mai 2009 à 20:18:33

          Comme je t'ai dit, seule la première exception levée est catchée, et le programme reprend à la fin du (ou des) catch. En l'occurence, la première exception trouvée, c'est NombreHabitantException. Le code s'arrête donc après ça :

          throw new NombreHabitantException(pNbre);
          


          Il saute directement là :

          catch (NombreHabitantException e) {
          


          Et il reprend normalement ici :

          System.out.println(v.toString());
          


          Bref, rien d'anormal dans ton code. Il s'arrête à la première erreur rencontrée (throw...), et il reprend une fois le traitement des erreurs terminé (catch...)

          Si tu veux traiter tes 2 erreurs à la fois, il ne faut pas passer par des exceptions (Ou les traiter aussitôt, ce qui n'a pas d'intérêt vu que tu les throw toi-même...)

          Bref, je peux pas te corriger, parce qu'il n'y a rien de faux. C'est juste un problème de compréhension de ta part :)
          • Partager sur Facebook
          • Partager sur Twitter
            28 mai 2009 à 20:24:08

            Parce qu'il traite la première Exception puis rentre dans ton premier catch, exécute ce qu'il y a dedans puis s'arrête, si tu veux qu'il rentre dans le deuxième bloc catch tu dois traiter ta seconde exception dans le premier bloc catch :
            Ville2 v = null;
            		try {                   
            			v = new Ville2("Re", -12000, "France");           
            		}
            		//Gestion de l'exception sur le nombre d'habitants
            		catch (NombreHabitantException e) {
            			e.printStackTrace();
                                    if (v.getNom().length < 3)
                                        throw new NomVilleException ("le nom de la ville est inférieur à 3 caractères ! nom = " + v.getNom());
            			v = new Ville2();
            		}
            		//Gestion de l'exception sur le nom de la ville
            		catch(NomVilleException e2){
            			System.out.println(e2.getMessage());
            			v = new Ville2();
            		}
            
            		System.out.println(v.toString());
            


            C'est l'endroit ou tu traite ton Exception qui va faire rentrer le programme dans le bloc catch, donc ce qui compte c'est ou mettre le throw et ou mettre le catch qui va avec.

            • Partager sur Facebook
            • Partager sur Twitter
              28 mai 2009 à 20:33:44

              Merci les amis pour vos explications.
              • Partager sur Facebook
              • Partager sur Twitter
                28 mai 2009 à 21:02:42

                @Lolilolight :

                Sauf que là, d'une part, ta VilleException n'est pas dans un try, et n'est donc pas catchée. D'autre part, elle ne sera vérifiée *que* si l'exception NombreHabitant est levée (Et catchée). Ou alors, il faut faire 2 fois le test.

                Pas terrible.

                Si tu veux tester toutes les erreurs, le plus simple c'est de pas utiliser les exceptions, mais un booléen. Un truc du style :

                void maMethode(){
                
                	boolean error = false;
                
                	if (! test1){
                		error = true;
                		System.err.println("Erreur 1");
                	}
                
                	if (! test2){
                		error = true;
                		System.err.println("Erreur 2");
                	}
                
                	if (...){
                		...
                	}
                
                	if (error){
                		return; //S'il y a une erreur, on arrête tout
                	}
                
                	//Si tout se passe bien, on effectue le traitement
                
                }
                
                • Partager sur Facebook
                • Partager sur Twitter
                  28 mai 2009 à 21:09:09

                  Ok, merci de ta réponse.

                  Si je comprends bine les Exception c'est bien mais pour "capturer" une seule erreur simultanément.

                  Sinon en effet, j'ai oublier le try.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 mai 2009 à 21:17:53

                    Il n'est pas possible de lancer plusieurs exception. Une exception correspond à un comportement anormal mettant en erreur la fonction/méthode concernée. Comme la méthode est en erreur, il est normal qu'elle s'arrête tout de suite après la levé de l'exception (ça ne sert à rien de continuer). D'ailleurs, pour vous en convaincre, la méthode retourne tout de suite après un throw (comme un return, sauf que ça retourne un Exception).

                    Prenez votre IDE, écrivez ce code :
                    public static void main (String[] args) throws Exception{
                        throw new Exception("foobar");
                        System.out.println("Après l'exception !");
                    }
                    


                    Il devrait vous mettre une erreur parce que le System.out ne sera jamais exécuté, ceci dû au fait que la méthode finit avec le throw.
                    • Partager sur Facebook
                    • Partager sur Twitter

                    Les exceptions

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown