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

Collection et Stream Java Discussion :

Instancier un tableau d'objets de type variable


Sujet :

Collection et Stream Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2016
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Septembre 2016
    Messages : 20
    Points : 11
    Points
    11
    Par défaut Instancier un tableau d'objets de type variable
    Bonjour

    J'utilise la réflexion pour construire un interpréteur. J'ai par exemple deux méthodes parmi une centaine :

    public void fonction35 (Enum quoi, int i, String s) { ...etc... }
    public void fonction42 (Enum quoi, int i, String... s) { ...etc... }

    L'appel de getMethods() sur la classe de l'interpréteur me permet de construire une table HashMap <String, Method> pour trouver les méthodes à partir de leur nom.

    Lorsqu'une méthode "m" a été ainsi trouvée, l'appel de m.getGenericParameterTypes permet d'avoir un tableau de types ("Type") pour les paramètres.

    Dans le cas de la méthode "fonction35", la taille de ce tableau est suffisante pour construire un tableau de paramètres afin d'appeler la méthode par m.invoke. Tout se passe bien si chaque paramètre dans ce tableau (Enum, (int), String) est rangé dans un Object [] sans se préoccuper de son type : m.invoke fait le tri à l'exécution.

    Tout se complique avec "fonction42" et son dernier paramètre qui est un tableau de String. On ne peut pas se permettre de déclarer ce dernier comme un Object [] car m.invoke, à l'exécution attend vraiment un String [] et pas autre chose ! du moins c'est ce que j'ai compris. Alors il me faut donc instancier dynamiquement ce String [] à partir du dernier objet contenu dans le tableau m.getGenericParameterTypes ().

    C'est là que je bloque. Comment instancier un tableau, de taille connue mais contenant des objets de types variés, grâce à un objet (une interface en fait) de type "Type" ?

  2. #2
    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
    Donc si je comprend bien tu as besoin d'instancier un tableau dont le type n'est connu qu'à l'exécution et que tu connais à partir d'un instance de Class<?>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Object[] tableau = Array.newInstance(type, taille);
    Array viens de java.lang.reflect

  3. #3
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2016
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Septembre 2016
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    OK c'est effectivement ce dont j'ai besoin. Mais comment récupérer le contenu du tableau rendu par l'appel de m.getGenericParameterTypes et l'utiliser comme le "type" donné dans l'exemple en réponse ? Autre possibilité, appeler m.getParameterTypes qui rend un tableau d'objets de type "Class" et instancier le tableau pour le dernier paramètre à partir de ces objets ?

  4. #4
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2016
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Septembre 2016
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    Ah, j'ai trouvé une solution, mais elle me parait lourde et bizarre. Une fois la méthode "m" trouvée je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Class [] classParam = m.getParameterTypes () ;
    int nombreParametresFormels = classParam.length ;
    Class classeDernierParametre = classParam [nombreParametresFormels - 1] ;
    // Etc... on construit le tableau tabParam [nombreParametresFormels] avec les premiers paramètres
    if (classeDernierParametre.toString().contains("[")) {
        // le dernier paramètre est de type X... (tableau) avec (int) taille éléments
        Object [] derniersParametres = (Object[]) Array.newInstance (classeDernierParametre.getComponentType(), taille) ;
        // etc... garnir ce tableau
        tabParam [nombreParametresFormels-1] = derniersParametres ;
        interpreteur.invoke (m, tabParam) ;
    } else { //... etc... cas plus simple sans tableau ;}

  5. #5
    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
    Houlà

    Alors pour savoir si la méthode est de type varargs (donc si le dernier paramètre est de type 0...n valeurs), il suffit d'appeler method.isVarArgs().
    Pour savoir si un classe est un tableau, il y a la méthode clazz.isArray()
    Pour connaitre le type de l'array, il y a la méthode clazz.getComponentType()

    Bien sur ce dernier type peux aussi être un array

  6. #6
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2016
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Septembre 2016
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    OK ça fonctionne, voilà la portion de code avec ces modifs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Class [] classParam = m.getParameterTypes () ;
    int nombreParametresFormels = classParam.length ;
    // Etc... on construit le tableau tabParam [nombreParametresFormels] avec les premiers paramètres
    if (m.isVarArgs()) {
        // le dernier paramètre est de type X... (tableau) avec (int) taille éléments
        Class contenuDernierParametre = classParam [nombreParametresFormels - 1].getComponentType() ;
        Object [] derniersParametres = (Object[]) Array.newInstance (contenuDernierParametre, taille) ;
        // etc... garnir ce tableau
        tabParam [nombreParametresFormels-1] = derniersParametres ;
        interpreteur.invoke (m, tabParam) ;
    } else { //... etc... cas plus simple sans tableau ;}
    C'est plus clean. Merci pour le coup de main. Je teste le truc sur mon jeu de test et je valide (ou pas)

  7. #7
    Membre à l'essai
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2016
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Chercheur en informatique

    Informations forums :
    Inscription : Septembre 2016
    Messages : 20
    Points : 11
    Points
    11
    Par défaut
    L'instanciation du tableau est correcte, le m.invoke passe dans un programme de test, mais sur mon (gros) programme réel ça ne passe pas. Autre bug ? Probablement. Je considère le problème comme résolu, même si je dois ouvrir un autre fil pour la suite des événements. Pas simple le "m.invoke"...

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

Discussions similaires

  1. Typer un objet de type variable
    Par Astro-Péptio dans le forum Général Java
    Réponses: 12
    Dernier message: 26/07/2011, 11h41
  2. instancier un tableau d'objet
    Par mazodo dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 14/08/2008, 12h33
  3. Changer le style d'un objet de type variable
    Par Hayato dans le forum 4D
    Réponses: 1
    Dernier message: 01/09/2006, 16h44
  4. Tableau d'objets de type différents
    Par Hell dans le forum C++
    Réponses: 9
    Dernier message: 11/01/2005, 23h57
  5. Tableau d'éléments de type variable
    Par Drooxy dans le forum Langage
    Réponses: 4
    Dernier message: 16/03/2003, 16h20

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