|
Création d'une instance d'une classe avec son nom |
Niveau : débutant/initié
Compatibilité : voir texteAu cours de l'exécution d'un programme, vous voulez créer un objet d'une classe dont le nom vous est donné sous forme de chaîne de caractères, par exemple "Button". Dans ce cas, il est impossible de créer cet objet grâce à l'opérateur new, puisque new requiert une classe et pas une chaîne de caractères contenant le nom de cette classe ; new "Button" () n'est pas accepté en Java.
La classe java.lang.Class déclare les deux méthodes forName () et newInstance (), qui permettent de récupérer une instance de Class à partir du nom complet d'une classe (package + nom de la classe) et de l'instancier si cette classe a un constructeur sans paramètre. Pour créer un objet de la classe Button, il suffit alors de programmer l'instruction suivante :Class.forName ("java.awt.Button").newInstance ()L'instruction précédente a une difficulté pratique d'utilisation : elle peut déclencher 3 types d'exceptions différents, qu'il est obligatoire d'intercepter. En effet, les méthodes forName () et newInstance () doivent effectuer le même travail que le compilateur et donc vérifier :
- si la classe donnée par son nom existe
- si elle n'est pas une classe abstract ou une interface
- si elle est accessible
- si elle a un constructeur accessible sans paramètre.
Et ce, même si vous savez parfaitement qu'aucune de ces exceptions ne sera jamais déclenchée. Vous obtenez alors :
try { Class.forName ("java.awt.Button").newInstance (); } catch (ClassNotFoundException e) { // La classe n'existe pas } catch (InstantiationException e) { // La classe est abstract ou est une interface ou n'a pas de constructeur accessible sans paramètre } catch (IllegalAccessException e) { // La classe n'est pas accessible }Grâce au package supplémentaire java.lang.reflect, Java 1.1 apporte la possibilité d'instancier toutes les classes (et les tableaux) en utilisant n'importe lequel de leur constructeur (avec ou sans paramètre).
La classe Class est enrichie des méthodes getDeclaredConstructor () et getDeclaredConstructors (), qui permettent de récupérer les constructeurs d'une classe, et les classes Constructor et Array déclarent elles aussi les méthodes newInstance ().
Si par exemple vous voulez créer une instance de la classe java.awt.Button en passant à son constructeur son label "Ok", vous obtenez alors :try { // Récupération de la classe java.awt.Button Class classe = Class.forName ("java.awt.Button"); // Récupération du constructeur prenant en paramètre une chaîne de caractères java.lang.reflect.Constructor constructeur = classe.getConstructor (new Class [] {Class.forName ("java.lang.String")}); constructeur.newInstance (new Object [] {"Ok"}); } catch (ClassNotFoundException e) { // La classe n'existe pas } catch (NoSuchMethodException e) { // La classe n'a pas le constructeur recherché } catch (InstantiationException e) { // La classe est abstract ou est une interface } catch (IllegalAccessException e) { // La classe n'est pas accessible } catch (java.lang.reflect.InvocationTargetException e) { // Exception déclenchée si le constructeur invoqué // a lui-même déclenché une exception } catch (IllegalArgumentException e) { // Mauvais type de paramètre // (Pas obligatoire d'intercepter IllegalArgumentException) }La méthode getConstructor () requiert en paramètre un tableau des classes que doit recevoir le constructeur recherché.
La méthode newInstance () requiert en paramètre un tableau d'objets qui correspondent à chacun des paramètres du constructeur invoqué.
|