IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Créer un objet dont la classe est une variable


Sujet :

Langage Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 16
    Points : 11
    Points
    11
    Par défaut Créer un objet dont la classe est une variable
    Bonjour à tous,
    je cherche la solution à un petit problème, je dois créer des objets dont la classe dépend de l'élément sélectionné dans une liste déroulante, je développe :
    J'ai une liste déroulante qui se remplie en fonction de fichiers ".java" qui se trouvent dans un package "modules". Ces fichiers sont mes classes. Par exemple :
    - ImportStations.java
    - ImportEnquetes.java
    - VérificationDesFiches.Java
    Ma liste déroulante affiche donc :
    - ImportStations
    - ImportEnquetes
    - VérificationDesFiches

    J'ai un bouton qui lance une action par son écouteur dans lequel je dois créer un objet de la classe de l'élément sélectionné dans la liste déroulante, par exemple :
    si j'ai sélectionné ImportStations et que je clique sur le bouton, mon écouteur doit créer un objet :
    ImportStations importStations = new ImportStations();
    Je voudrais le faire sans donner la classe mais en utilisant l'élément sélectionné de la liste un truc du genre (je sais que ce que je vais donner comme exemple est faux c'est juste pour expliquer le principe)
    this.fenetre.getListeActions().getSelectedItem() monObjet= new this.fenetre.getListeActions().getSelectedItem()();

    Quelqu'un a-t-il un piste à me donner ?
    Merci à tous et bonne journée.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 628
    Points : 10 553
    Points
    10 553

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Merci beaucoup, je vais jeter tout de suite un oeil sur le fonctionnement de ce Class.forName()

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    oui enfin, sauf cas particulier, ça reste moche:

    Ton programme n'auras pas, au final, accès aux .java => comment va-tu scanner? les .class?
    Si tu scanne les .class, tu aura les classes anonyme et les InnerClass qui seront visible => tu ne veux / peux pas les instancier

    Le plus simple reste d'avoir un système relativement propre de configuration. Genre tu fais une Enum avec les valeurs possible, et c'est l'enum qui se charge d'instancier:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public enum Valeurs{
     
    public abstract Object instanciate();
       IMPORT_STATIONS(){
          public Object instanciate(){return new ImportStations();}
       },
       IMPORT_ENQUETE(){
          public Object instanciate(){return new ImportEnquetes();}
       }
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((Valeurs)comboBox.getSelectedItem()).instanciate();
    Possible uniquement si tu sais tout ça à la compilation.
    Si ça doit être dynamique, avoir au minimum un fichier de configuration pour définir les valeurs possibles.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Merci tchize_ pour ton approche, c'est de cette façon que je comptais envisager le truc, le hic, mon boss ne veut pas que les classes apparaissent, il veut que l'outil soit évolutif sans plus jamais mettre les mains dans le code, en gros il veut développer les classes du package module et que le reste se fasse tout seul en fonction de ce qui se trouve dans le package, donc pas de maintenance de fichier config, en fait pas de fichier de config du tout, ordres du chef .

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Tu peux utiliser des libriaries annexe? Parce que, si tu développe ton scanner toi même, tu va en ch*** et ce sera instable, il y a tellement de cas à gérer pour scanner les classes d'un package.
    De plus, comme je l'ai dit, tu va inévitablement te retrouver avec, dans ce module, des classes Machin$1 Machin$2 Machin$Truc que tu n'as probablement pas envie d'exposer . Je dirais que la première chose à exposer à ton boss, ce sont les problèmes que cela va inévitablement entrainer en production, les erreurs, les coûts de maintenance. Parce que si il veux tout automatique, tu aura inévitablement:

    des dev qui vont faire des constructeurs avec arguments
    des dev qui vont faire des inner classes et des anonymous class
    des dev qui iront tapper le truc dans un sous package
    des devs qui laisseront des classes appelées ImportFactureClientMachinQuiFaitChier


    Une solution peut être acceptable pour lui serait d'utiliser les scanner de Spring (soit en utilisant Spring IOC, soit en appelant directement les classes de scanning de spring) pour scanner un package X à la recherche d'annotations bien précise. Je ne connais pas le contexte de cet outils, mais pour un utilisateur final, sans un minimum de collaboration du dev, tu risque d'avoir des trucs "bizarres" à l'écran.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    En fait, le principe est assez simple, chaque classe ne fait qu'une seule chose, une maintenance particulière dans une base oracle, "une classe, une action". Dans chaque classe il y a un String message, dans lequel on stocke le message que l'on affichera une fois l'action terminée. Les méthodes servant à faire l'action sont lancées dans le constructeur, donc en gros de l'extérieur on n'utilise que le constructeur et getMessage().

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 628
    Points : 10 553
    Points
    10 553
    Par défaut
    Et JCL?

    Tu crées un jar et tu le charges.
    Éventuellement, dans le pire des cas, tu fais un appel système pour créer le jar à partir de tes fichiers source ... à tous les problèmes près

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Merci.
    JCL, je ne connais pas du tout, j'explore la piste du Class.forName que je n'arrive pas à faire fonctionner pour le moment, et je regarderai après.

  10. #10
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    JCL ne te donne pas la liste des classes chargées. Il va servir à quoi au juste ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Si tes classes implémentent une interface particulière (avec getMessage dedans) au moins ça devrait te permettre de filtrer les classes annexes.

    Vu l'usage, selon mois, le plus propre, ce serait d'avoir un annotation sur chaque classe, du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    @OracleAction(title="titre pour combobox", message="message une fois l'action finie")
    public class ImportAction{
    }
    Ce serait déjà bien plus dans l'esprit de java actuel et ne présuposerais pas de choses hard comme pas d'inner class, pas d'anonymous class, etc. Après, pour avoir la liste des classes annotées "OracleAction", tu pourrais réutiliser les scanner comme Reflections:

    https://code.google.com/p/reflections/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      Reflections reflections = new Reflections("com.company.oracle.actions");
         Set<Class<?>> annotated = 
                   reflections.getTypesAnnotatedWith(OracleAction.class);

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    Merci à tous pour ces informations précieuses, j'ai trouvé une solution qui semble bien fonctionner.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    String elementListe=(String)this.fenetre.getListeActions().getSelectedItem();
     
    Class<?> classe=(Class<?>) Class.forName("main.modules."+elementListe);
    Object objet=classe.newInstance();
    Method m=null;
    for(int i=0; i<classe.getMethods().length; i++)
    {
        if(classe.getMethods()[i].getName().equals("getMessage"))
        {
            m=classe.getMethods()[i];
        }
    }
     
    if(methode==null)
    {
        message="Pas de message de sortie";
    }
    else
    {
        message=(String) methode.invoke(objet);
    }

  13. #13
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Il serait quand même plus propre que les méthodes implémentent un interface commune. Si c'est pour forcer l'existance d'une méthode getMessage :/


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface MessageProvider{
       public String getMessage();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Class<?> classe=(Class<?>) Class.forName("main.modules."+elementListe);
    Object objet=classe.newInstance();
    if (object instanceOf MessageProvider)
     message = ((MessageProvider)object).getMessage();
    else
     message = "Pas de message";
    C'est quand même plus lisible.

  14. #14
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Du coup l'idée qu'il y a pas besoin de mettre des infos en plus que juste les classes dans le package, hop, à la trappe ?
    Parce que bon, getListeActions().getSelectedItem() ne s'est pas remplie par l'opération du Saint Esprit.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 16
    Points : 11
    Points
    11
    Par défaut
    tchize_ : Merci pour ton approche, mais là ça devient bien trop compliqué pour que je le comprenne

    thelvin : Je n'avais pas été clair, le package modules ne sert qu'à mettre les classes que je vais faire apparaitre dans ma liste déroulante. "getListeActions().getSelectedItem() ne s'est pas remplie par l'opération du Saint Esprit", en effet, mais comme ça ne concernait pas la question initiale, je n'avais pas mis le bout de code qui le fait.

  16. #16
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Une interface, c'est trop compliqué ? Arrête java tout de suite alors! Parce que avec les classes, ça forme quand même la base du langage.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Module dont le nom est une variable
    Par Mr Hyde dans le forum Général Python
    Réponses: 11
    Dernier message: 26/02/2023, 20h39
  2. Réponses: 10
    Dernier message: 02/07/2021, 17h44
  3. Delaration d'un objet dont sa classe implemente une Interface
    Par handsome01 dans le forum Général Java
    Réponses: 2
    Dernier message: 02/11/2012, 03h20
  4. Créer un objet dont le nom est issu d'un String
    Par Claude_Azoulai dans le forum VB.NET
    Réponses: 7
    Dernier message: 05/04/2010, 14h02
  5. Instancier une classe dont le nom est une variable
    Par bendev dans le forum Langage
    Réponses: 1
    Dernier message: 06/11/2006, 06h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo