Instanciation d'une classe dont le nom est dans une variable [Résolu]

sphaxslayer 216 Messages postés mardi 5 avril 2005Date d'inscription 17 septembre 2008 Dernière intervention - 16 janv. 2008 à 10:02 - Dernière réponse : sphaxslayer 216 Messages postés mardi 5 avril 2005Date d'inscription 17 septembre 2008 Dernière intervention
- 16 janv. 2008 à 13:26
Bonjour tout le monde,

voilà j'ai un petit souci qui est en fait je pense la question la plus tordue du monde entier et de l'univers. J'ai un système d'héritage de classes Filtres. Chaque nom de classe (et donc du fichier .java...) est enregistré en base et donc récupérable. Ces "filtres" sont sélectionnés et on construit un ArrayList de leur noms en fonction de ceux qu'on a sélectionnés.

Ma question est la suivante : est-il possible de déclarer une variable dont le type serait la valeur d'une autre. Exemple :

new (ArrLst.get(0)) filter1;
new (ArrLst.get(1)) filter2;
avec ArrLst.get(0) MathFilter , ArrLst.get(1) PunctuationFilter
et 2 classes existantes : MathFilter.java, PunctuationFilter.java

Merci d'avance... Bien qu'à mon avis, la réponse est claire :(

"Un seul Être vous manque, et tout est dépeuplé..."
Afficher la suite 

Votre réponse

4 réponses

Meilleure réponse
Twinuts 5280 Messages postés dimanche 4 mai 2003Date d'inscription 3 octobre 2018 Dernière intervention - 16 janv. 2008 à 12:54
3
Merci
Salut,

en gros si je comprend bien tu veux créer une instance d'un objet sans passer par sa référence directe mais seulement par son nom.

Bah jusque là aucun problème en java c'est faisable. Pour ce faire tu dois utiliser le mécanisme de réflexion... voici deux solutions (les plus courantes) :
 1 – L'objet que tu veux instancier possède un constructeur vide (sans argtuments).
 2 – L'objet que tu veux instancier contient 1 ou plusieurs constructeurs avec argument.

solution 1 :
L'exemple ci-dessous montre comment instancier la classe java.util.Random (te suffit d'adapter pour ton code)

import java.lang.reflect.Method;

public class Test {

    public static void main(String[] args) {
        // Note : ce bout de code trapue toutes les exception, et ne fait pas de test sur la validité
        // des champs.
        // ATTENTION: l'utilisation de la réflexion alourdi le temps de traitement d'un code
        try {
            // Lorsque tu veux instancier un objet par son nom il te faut le nom complet
            // soit le nom de ton objet mais pas seulement, il te faut également
            // connaître l'emplacement de ta classe (dans quel package elle se trouve).
            String className = "java.util.Random";
            // la méthode forName(...) permet de demander à la JVM de trouver le byte code
            // associé à un objet Class, afin de pouvoir le manipuler ultérieurement.
            Class<?> classRandom = Class.forName(className);
            // Affichage de la classe.
            System.out.println(classRandom);
            // Demande à la JVM de trouver le constructeur vide de ton objet
            // afin de créer une instance dessus.
            Object objectRandom = classRandom.newInstance();
            // Affichage de l'instance sur l'objet Random.
            System.out.println(objectRandom);
            // Invocation d'une méthode afin de tester si tout ce passe comme prévu ^^.
            // La première étape consiste à trouver la méthode dans l'objet Random
            // pour le test nous allons nous intéresser à la méthode nextInt(int).
            Method nextInt = classRandom.getMethod(
                    "nextInt", // Nom de la méthode qui nous intéresse.
                    // Il faut ensuite indiquer le type des paramètres de la méthode
                    // en l'occurrence ici on choisi la méthode ayant un paramètre de type int.
                    new Class[] { int.class }
            );
            // Affichage de la méthode
            System.out.println(nextInt);
            // Maintenant il suffit d'invoquer la méthode en question et de traiter le résultat.
            Object result = nextInt.invoke(
                    objectRandom, // Référence sur l'objet propriétaire de la méthode.
                    // Il faut ensuite indiquer la valeur des paramètres de la méthode
                    // en l'occurrence ici on a choisi la méthode ayant un paramètre de type int
                    // donc on lui met une valeur... par exemple... "50".
                    new Object[] { 50 }
            );
            // Exploitation du retour de la méthode (nextInt retourne un entier).
            int value = (Integer)result;
            // Affichage de la valeur
            System.out.println(value);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

solution 2:
L'exemple ci-dessous montre comment instancier la classe java.io.File (te suffit d'adapter pour ton code)
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Test {

    public static void main(String[] args) {
        // Note : ce bout de code trappe toutes les exception, et ne fait pas de test sur la validité
        // des champs.
        // ATTENTION: l'utilisation de la réflexion alourdi le temps de traitement d'un code
        try {
            // Lorsque tu veux instancier un objet par son nom il te faut le nom complet
            // soit le nom de ton objet mais pas seulement, il te faut également
            // connaître l'emplacement de ta classe (dans quel package elle se trouve).
            String className = "java.io.File";
            // la méthode forName(...) permet de demander à la JVM de trouver le byte code
            // associé à un objet Class, afin de pouvoir le manipuler ultérieurement.
            Class<?> classFile = Class.forName(className);
            // Affichage de la classe.
            System.out.println(classFile);
            // Maintenant il faut spécifier le type de constructeur à utiliser afin de créer une instance de la classe File
            // Pour ce faire, on utilise l'objet Constructor du package reflect.
            // L'instance de l'objet Constructor ce fait par l'intermediaire de la méthode getConstructor en spécifiant le constructeur
            // de notre choix, soit ici celui qui prend en paramètre un String
            Constructor<?> constructorFile = classFile.getConstructor(new Class[] {String.class});
            // Affichage de l'instance sur l'objet Constructor de la classe File.
            System.out.println(constructorFile);
            // Demande à la JVM de trouver le constructeur prenant en paramètre un String
            // afin de créer une instance dessus.
            Object objectFile = constructorFile.newInstance(new Object[] { "./fichier.txt" }); // on passe en paramètre le nom d'un fichier pour que la classe File se cale dessus ^^
            // Affichage de l'instance sur l'objet File.
            System.out.println(objectFile);
            // Invocation d'une méthode afin de tester si tout ce passe comme prévu ^^.
            // La première étape consiste à trouver la méthode dans l'objet File
            // pour le test nous allons nous intéresser à la méthode exists().
            Method exists = classFile.getMethod(
                    "exists", // Nom de la méthode qui nous intéresse.
                    // Il faut ensuite indiquer le type des paramètres de la méthode
                    // en l'occurrence ici on choisi la méthode n'ayant aucun paramètre.
                    new Class[] {}
            );
            // Affichage de la méthode
            System.out.println(exists);
            // Maintenant il suffit d'invoquer la méthode en question et de traiter le résultat.
            Object result = exists.invoke(
                    objectFile, // Référence sur l'objet propriétaire de la méthode.
                    // Il faut ensuite indiquer la valeur des paramètres de la méthode
                    // en l'occurrence ici on a choisi la méthode n'ayant aucun paramètre.
                    new Object[] {}
            );
            // Exploitation du retour de la méthode (exists retourne un boolean).
            boolean value = (Boolean)result;
            // Affichage de la valeur
            System.out.println(value);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO

Merci Twinuts 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 95 internautes ce mois-ci

Commenter la réponse de Twinuts
KenZara 112 Messages postés vendredi 24 décembre 2004Date d'inscription 20 décembre 2011 Dernière intervention - 16 janv. 2008 à 11:56
0
Merci
    Bonjour,

A mon avis ce que tu cherches à faire n'est pas possible :/ .... Mais détaille nous un peu plus, il se peut que j'ai mal compris ce que tu veux faire.
En tout cas faire ça: ArrLst.get(0) == MathFilter sachant que le MathFilter est le nom de la classe, hum je ne pense pas...

Voilou ... Sinon j'adore ton message de fin :) ...

Kenza
Commenter la réponse de KenZara
sphaxslayer 216 Messages postés mardi 5 avril 2005Date d'inscription 17 septembre 2008 Dernière intervention - 16 janv. 2008 à 13:20
0
Merci
Salut,
et merci de ta réponse.. Effectivement tu as bien compris à mon avis, j'aurais voulu pouvoir instancier un objet d'un type donné par la valeur d'une variable, c'est bien ça... Tant pis, en "bricolage" j'ai fait un bloc de if..else if... laid pas beau (pour l'instant j'ai que 3 classes de filtres, mais dans un temps t à venir, il se pourrait qu'il y en ait une petite dizaine par exemple...)

... ahh... si le switch marchait sur les chaînes de caractères en Java...

Quant à ma signature, il s'agit d'une citation d'Alphonse de Lamartine, parodié d'ailleur par Woodie Allen en "Un seul être vous manque et c'est justement celui qui vous doit de l'argent" ou quelque chose du genre :-)

Merci en tous cas, de confirmer ma supposition... J'ai feinté pour le moment, je pense que le système général de nos classes est à reprendre mais bon...

"Un seul Être vous manque, et tout est dépeuplé..."
Commenter la réponse de sphaxslayer
sphaxslayer 216 Messages postés mardi 5 avril 2005Date d'inscription 17 septembre 2008 Dernière intervention - 16 janv. 2008 à 13:26
0
Merci
Ah, j'avais pas actualisé la page, merci pour ton exemple complet et détaillé Twinuts, ca me parait convenir, je vais tester ça : j'ignorais totalement l'existence d'un Class<?> ... ce qui tombe plutôt bien je dirais :-)

"Un seul Être vous manque, et tout est dépeuplé..."
Commenter la réponse de sphaxslayer

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.