Programmation 2 : cinquième cours

Arnaud Labourel

21 octobre 2019

Surcharge de méthode/constructeurs

Méthodes ayant le même nom

Dans une classe, plusieurs méthodes peuvent avoir le même nom.

C’est ce qu’on appelle la surcharge de méthode.

Il est par contre nécessaire que la séquence dans l’ordre des types des arguments soit différente pour chaque méthode ayant le même nom.

La méthode est choisie par le compilateur de la façon suivante :

  • Le nombre de paramètres doit correspondre
  • Les affectations des paramètres doivent être valides
  • Parmi ces méthodes, le compilateur choisit la plus spécialisée, c’est-à-dire celle entraînant le moins de changement de types (passage à une super-classe ou promotion pour les types primitifs)

Exemple de surcharge de méthode

Exemple de surcharge de méthode

Exemple de surcharge de méthode

Promotion pour les types primitifs

Si les types des arguments ne correspondent pas aux types des paramètres, les types des arguments sont promus en suivant les flèches :

image

Exemple de surcharge de méthode

Pour les instances de classe, c’est le type du conteneur à la compilation qui compte.

Plusieurs constructeurs

C’est exactement les mêmes règles qui s’appliquent pour les constructeurs d’une classe.

Exceptions

Les exceptions

Un programme peut être confronté à une condition exceptionnelle (ou exception) durant son exécution.

Une exception est une situation qui empêche l’exécution normale du programme (elle ne doit pas toujours être considérée comme un bug). Quelques exemples de situations exceptionnelles :

  • un fichier nécessaire à l’exécution du programme n’existe pas,
  • une division par zéro,
  • un débordement dans un tableau,
  • un besoin de se connecter à un serveur et celui-ci est injoignable,
  • un dépilement d’une pile vide,

Mécanisme de gestion des exceptions

Java propose un mécanisme de gestion des exceptions afin de distinguer l’exécution normale du traitement de celles-ci afin d’en faciliter leur gestion.

En Java, une exception est concrétisée par une instance d’une classe qui étend la classe Exception.

Pour lever (déclencher) une exception, on utilise le mot-clé throw :

Pour capturer une exception, on utilise les mots-clés try et catch :

Exemple d’exceptions existantes en java

  • ArithmeticException : opération arithmétique impossible comme la division par 0.
  • IndexOutOfBoundsException : dépassement d’indice dans un tableau, un vecteur, …
  • NullPointerException : accès à un attribut/méthodes/case pour les tableaux d’une référence valant null, argument null alors que ce n’est pas autorisé.
  • FileNotFoundException : échec de l’ouverture d’un fichier à partir d’un chemin.
  • IllegalArgumentException : argument incorrect (en dehors des valeurs autorisées) lors de l’appel d’une méthode.
  • NoSuchElementException : next alors que l’itération est finie, dépilement d’une pile vide, …

Définir son exception

Il suffit d’étendre la classe Exception (ou une classe qui l’étend) :

La syntaxe try/catch

Pour capturer une exception, on utilise la syntaxe try/catch :

test(11) test(13)
A B A B
C D MyException: Error 13
D

Exceptions et signatures des méthodes

Une méthode doit préciser dans sa signature toutes les exceptions qu’elle peut lever et qu’elle n’a pas traitées avec un bloc try/catch :

La méthode testValue peut lever une exception de type MyException.

runTestValue doit indiquer qu’elle peut lever une exception car elle ne gère pas l’exception provoquée par l’appel testValue(value).

Important

Si aucune des deux propriétés est vérifiée alors il y a une erreur à la compilation.

Error:(YY, XX) java: unreported exception MyException;
      must be caught or declared to be thrown

Gestions des exceptions : règle

La méthode runTestValue peut lever une exception (de type MyException).

Lorsqu’on fait un appel à la méthode runTestValue, il est vérifié à la compilation que l’une des deux propriétés suivante est vraie :

  • la méthode appelant runTestValue est indiquée comme pouvant lever l’exception MyException (en écrivant throws MyException à la signature de la méthode).
  • l’exception potentielle est capturée par un loc try/catch.

Si aucune des deux propriétés est vérifiée alors il y a une erreur à la compilation.

Error:(YY, XX) java: unreported exception MyException; 
      must be caught or declared to be thrown

Exceptions et signatures des méthodes

Une méthode doit donc préciser dans sa signature toutes les exceptions qu’elle peut lever et qu’elle n’a pas traitées avec un bloc try/catch

On doit donc écrire :

Techniquement la méthode main pourrait indiquer qu’elle génère l’exception MyException mais cela n’aurait pas beaucoup de sens car cela voudrait dire qu’on ne gère pas vraiment l’exception.

Méthode printStackTrace

La méthode printStackTrace permet d’afficher la pile d’appels :

La classe RuntimeException

Une méthode doit indiquer toutes les exceptions qu’elle peut lever sauf si l’exception étend la classe RuntimeException Bien évidemment, la classe RuntimeException étend Exception.

Quelques classes Java qui étendent RuntimeException :

  • ArithmeticException
  • ClassCastException
  • IllegalArgumentException
  • IndexOutOfBoundsException
  • NegativeArraySizeException
  • NullPointerException
  • NoSuchElementException

Notez que ces exceptions s’apparentent le plus souvent à des bugs.

Description de la classe RuntimeException dans la documentation Java

RuntimeException is the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine.

RuntimeException and its subclasses are unchecked exceptions. Unchecked exceptions do not need to be declared in a method or constructor’s throws clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary.

Règle générale : ajout cas RuntimeException

Lorsqu’on fait un appel à une méthode canThrow pouvant lever une exception MyException qui n’étend pas RuntimeException, il est vérifié à la compilation que l’une des deux propriétés suivantes est vraie :

  • la méthode appelant canThrow dans son code est indiquée comme pouvant lever une exception de type MyException ou une de ces super-classes (en écrivant throws MyException à la signature de la méthode).

  • l’exception potentielle est capturée par un bloc try/catch.

Capturer une exception en fonction de son type

Le mot-clé finally

On rajouter un bloc finally après des blocs try. Le bloc associé au mot-clé finally est toujours exécuté :

FileNotFoundException étend IOException et donc elle est capturée

Gestion de différents types d’exceptions

Exceptions pour des piles (1/2)

Exceptions pour des piles (2/2)

Définition des exceptions pour les piles

Exemple d’utilisation (1/2)

Exemple d’utilisation (2/2)

Les énumérations

Énumérations en Java

En programmation, une énumération est un type spécial qui permet de définir des variables pouvant prendre des valeurs parmi un ensemble prédéfini de constantes.

Il est possible de définir des énumérations en Java grace au mot-clé enum

Énumérations en Java

Une énumération est une classe avec des éléments prédéfinis et statiques.

On peut donc tester directement l’égalité avec l’opérateur égal car il n’y qu’un objet et donc qu’une référence qui correspond à chaque valeur possible.

Définition de champs, de méthodes et d’un constructeur

Classe Enum

Toutes les énumération de java étendent la classe Enum.

Quelques méthodes utiles :

  • String name() : retourne le nom de la constante tel que déclaré dans l’enum.
  • int ordinal() : retourne la position de la constante dans la déclaration de l’enum (commençant par 0).

Tout enum définit aussi une méthode statique values() renvoyant un tableau contenant les constantes dans l’ordre de leurs déclarations.

Exemple d’utilisation d’énumération (1/2)

Affichage :

Le symbole de Pique est Pi.
Le symbole de Coeur est Co.
Le symbole de Carreau est Ca.
Le symbole de Trèfle est Tr.

Exemple d’utilisation d’énumération (2/2)

Affichage :

The position of SPADES is 0
The position of HEARTS is 1
The position of DIAMONDS is 2
The position of CLUBS is 3

Mot-clé switch et enum

Supossons qu’on est une enum pour les jour de la semaine :

Mot-clé switch et enum

Mot-clé final

Première utilisation du mot-clé final

Mot-clé final dans la déclaration d’un attribut : interdit la modification de la valeur de l’attribut après la construction de l’objet.

Exemple :

  • Un attribut final doit être initialisé après la construction de l’instance
  • La valeur de l’attribut ne peut plus être modifiée ensuite

Deuxième utilisation du mot-clé final

Mot-clé final dans la déclaration d’une variable : interdit la modification de la valeur de la variable après la première affectation.

Troisième utilisation du mot-clé final

Mot-clé final dans la déclaration d’une méthode : interdire la redéfinition d’une méthode dans une sous-classe

  • Une classe étendant Integer ne peut pas redéfinir (donner une nouvelle implémentation) la méthode add

Quatrième utilisation du mot-clé final

Mot-clé final dans la déclaration d’une classe : interdit l’extension de la classe

  • Il devient impossible de créer une classe étendant Integer
  • On le fait souvent pour des raisons de sécurité et d’efficacité
  • De nombreuses classes de la bibliothèque standard de Java sont final comme Math, String et System