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 :

Déclaration de tableau du type Class..


Sujet :

Collection et Stream Java

  1. #1
    Membre confirmé
    Inscrit en
    Février 2006
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 117
    Par défaut Déclaration de tableau du type Class..
    Bonjour,

    Ma méthode possède un parametre qui est : A l’intérieur de cette méthode, j'aimerais déclarer un tableau contenant des objets du type de la classe donnée en paramètre :

    J'ai essayé ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cl tableau[] = new cl[2];
    le compilateur veut pas.

    et ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cl tableau[] = (cl) Array.newInstance(cl, 0);
    non plus..


    Je commence à me demander si c'est possible ..

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Non tu ne peux pas utiliser une variable comme un type. Ce n'est pas la même chose...


    Quel est l'objectif final de tout cela ?


    a++

  3. #3
    Membre confirmé
    Inscrit en
    Février 2006
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 117
    Par défaut
    Pour l'explication :

    La méthode en question:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     public Cmr init(Class cl,Integer pkValue)
    A l’intérieur de cette méthode, je dois créer une instance d'objet dynamiquement.
    Pour créer cette instance j'ai un constructeur avec un paramètre de type tableau de CmrLigne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public Cmr(Integer idCmr,Date date,CmrLigne cmrligne[])
    Lors de l'utilisation de ma methode init, je passe en paramètre la classe suivante : Et donc je dois créer un tableau de CmrLigne.class pour pouvoir alimenter le constructeur dynamique...

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Euh... quel est l'intérêt de passer par du code dynamique puisque le type est fixe ?!

    Si tu veux vraiment faire cela il faudra faire tout l'appel via la reflection, mais je ne comprend pas ce qui t'empêche de faire un appel direct.


    a++

  5. #5
    Membre confirmé
    Inscrit en
    Février 2006
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 117
    Par défaut
    La methode init que j'ai décrit est simplifiée..

    En fait, je ne connais pas le type Cmr, je le passe dans le parametre Class cl et ce n'est que par récursivité que j'obtiens le type de CmrLigne...
    Je ne connais donc pas le type cmrligne au départ.(sinon effectivement suffirait de passer CmrLigne [] en paramètre...)

    En résumé, à l'interieur de ma methode, mon code permet d'obtenir un tableau d'objet et dans ce tableau je n'ai que des élements de type CmrLigne.
    A ma disposition j'ai un Class cl (qui est le .class de CmrLigne).
    Le probleme est que je n'arrive pas à faire un cast avec (cl[]) le compilateur refuse...

  6. #6
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jeffciara Voir le message
    La methode init que j'ai décrit est simplifiée..
    Dans ce cas donnes nous un exemple concret, ou mieux ton vrai code !


    Si tu simplifies ton problème tu auras des solutions simplifiés qui ne correspondront pas à ton besoin...


    a++

  7. #7
    Membre confirmé
    Inscrit en
    Février 2006
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 117
    Par défaut
    Bon ben bon courage...

    Concrètement, je veux initialiser un objet de type Table à partir des données en base.

    Voici la méthode init :


    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
       public static Table init(Class cl, Integer primaryKeyValue) {
            Table table = null;
            String primaryKeyName;
            //Recherche du nom de la cle primaire
            ResultReq rrPk = Gestion.baseTest.requete("SELECT column_name " +
                    "FROM information_schema.key_column_usage " +
                    "WHERE CONSTRAINT_SCHEMA = '" + Gestion.nomBase + "' AND " +
                    "constraint_name='primary' AND table_name='" + cl.getSimpleName().toLowerCase() + "'");
            if (rrPk.getRowCount() > 0) {
                primaryKeyName = rrPk.getString(1);
            } else {
                Log.doLog(Level.SEVERE, OneLog.PERROR, "Pas de clé primaire trouvée pour la table :" + cl.getSimpleName());
                return null;
            }
            rrPk.closeStatement();
     
            // Recherche des param du constructeur
            // Je permet l'acces au tableau [0] car un seul constructeur pour les
            // types Table
            Constructor<?> constructor[] = cl.getDeclaredConstructors();
            Class classParamConstructeur[] = constructor[0].getParameterTypes();
            Object paramConstructeur[] = new Object[classParamConstructeur.length];
     
            // Recup du nom des champs pour la requete SQL
            Field champs[] = cl.getDeclaredFields();
            String listeChamps = "";
     
            // Si notre Table contient des soustables je les stocke la dedans..
            Map sousTables = new HashMap();
     
            for (int i = 0; i < champs.length; i++) {
                //On verifie si un parametre est de type SousTable
                Class sousTable = null;
                if (classParamConstructeur[i].getComponentType() != null) {
                    for (int j = 0; j < classParamConstructeur[i].getComponentType().getInterfaces().length && sousTable == null; j++) {
                        if (classParamConstructeur[i].getComponentType().getInterfaces()[j] == SousTable.class) {
                            sousTable = classParamConstructeur[i].getComponentType();
                        }
                    }
                }
                //Si un parametre de type SousTable est trouvé :
                if (sousTable != null) {
                    ResultReq rr = Gestion.baseTest.requete("SELECT * from " +
                            sousTable.getSimpleName().toLowerCase() + " where " +
                            primaryKeyName + " = " + primaryKeyValue, true);
                    Object sousClasse[] = new Object[rr.getRowCount()];
                    for (int j = 0; j < sousClasse.length; j++) {
                        String primaryKeyNameSousTable = "";
                        ResultReq rrPkSousTable = Gestion.baseTest.requete("SELECT column_name " +
                                "FROM information_schema.key_column_usage " +
                                "WHERE CONSTRAINT_SCHEMA = '" + Gestion.nomBase + "' AND " +
                                "constraint_name='primary' AND table_name='" + sousTable.getSimpleName().toLowerCase() + "'");
                        if (rrPkSousTable.getRowCount() > 0) {
                            primaryKeyNameSousTable = rrPkSousTable.getString(1);
                        } else {
                            Log.doLog(Level.SEVERE, OneLog.PERROR, "Pas de clé primaire trouvée pour la table :" + cl.getSimpleName());
                            return null;
                        }
                        sousClasse[j] = init(sousTable, rr.getInt(primaryKeyNameSousTable));
                        rr.next();
                    }
                    sousTables.put(i, sousClasse);
                } else {
                    //On continue d'inserer nos champs car l'objet soustable 
                    //n'a pas sa place dans la requete sql..
                    if (listeChamps.isEmpty()) {
                        listeChamps = champs[i].getName();
                    } else {
                        listeChamps = listeChamps + "," + champs[i].getName();
                    }
                }
            }
            String requete = "SELECT " + listeChamps + " FROM " + cl.getSimpleName() +
                    " WHERE " + primaryKeyName + " = '" + primaryKeyValue + "'";
            ResultReq rr = Gestion.baseTest.requete(requete.toLowerCase(), true);
            int j = 1;
            for (int i = 0; i < paramConstructeur.length; i++) {
                if (sousTables.containsKey(i)) {
                    // CEST ICI QUE JE DOIS FAIRE UN CAST AVEC LE TYPE DE LA CLASSE
                    // DONNé EN PARAMETRE
                    paramConstructeur[i] = sousTables.get(i);
                } else {
                    paramConstructeur[i] = rr.getObject(j);
                    j++;
                }
            }
            try {
                table = (Table) constructor[0].newInstance(paramConstructeur);
            } catch (InstantiationException ex) {
                ex.printStackTrace();
            } catch (IllegalAccessException ex) {
                ex.printStackTrace();
            } catch (IllegalArgumentException ex) {
                ex.printStackTrace();
            } catch (InvocationTargetException ex) {
                ex.printStackTrace();
            }
            return table;
        }

    C'est à ce niveau que je dois faire un cast (ligne81):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     paramConstructeur[i] = sousTables.get(i);

    Voici l'appel à la méthode :
    Voici le constructeur de Cmr (qui est une classe qui implémente Table ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public Cmr(Integer idCmr, Date date, Integer idClient, Integer idTransporteur, Integer qtePaletteEuro, Integer qtePaletteGrande, Integer qtePalettePetite, Integer temperature, String heureLivraison, CmrLigne[] cmrLigne)

    Et le constructeur de CmrLigne (qui est une classe qui implémente Table et SousTable )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public Cmr(Integer idCmr, Date date, Integer idClient, Integer idTransporteur, Integer qtePaletteEuro, Integer qtePaletteGrande, Integer qtePalettePetite, Integer temperature, String heureLivraison, CmrLigne[] cmrLigne)

    En cherchant dans le forum je me suis rendu compte que ma recherche porte un nom c'est du cast dynamique. A priori impossible avec un tableau, comme tu dis ...

  8. #8
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Ben comme tu passes tout par la reflection, il faut donc utiliser la reflection pour créer ton tableau avec le bon type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    // Object sousClasse[] = new Object[rr.getRowCount()];
    Object sousClasse[] = Array.newInstance(sousTable, rr.getRowCount());

    après le gros problème que je vois, c'est que tu te base sur la liste des champs de la classe pour initialiser les paramètres du constructeur. La moindre différence à ce niveau risque d'être fatale...

    Il serait peut-être préférable de passer par un constructeur vide et des setters...


    a++

  9. #9
    Membre confirmé
    Inscrit en
    Février 2006
    Messages
    117
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 117
    Par défaut
    En effet ça marche...
    Avec une petite rectification :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Object sousClasse[]  = (Object[]) Array.newInstance(sousTable, rr.getRowCount());
    Bizarre quand même après un cast et une affectation il garde encore le pointeur vers le tableau sousTable...


    c'est que tu te base sur la liste des champs de la classe pour initialiser les paramètres du constructeur
    En effet, je pourrais peut être créer un constructeur spécifique pour l’accès à la base de données.

    Merci à toi en tout cas ! tu m'as bien aidé et a compris mon code lol.

    Tiouss

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 23/04/2013, 19h29
  2. [Tableaux] Déclaration d'un tableau dans une classe
    Par rochenico dans le forum Langage
    Réponses: 4
    Dernier message: 22/12/2006, 11h29
  3. Initialisation d'un tableau de type STRUCT
    Par Axiome dans le forum MFC
    Réponses: 4
    Dernier message: 06/09/2005, 10h58
  4. Réponses: 13
    Dernier message: 25/03/2005, 11h00
  5. [Debutant]reallocation de memoire d'un tableau de type perso
    Par killerjeff dans le forum Débuter
    Réponses: 3
    Dernier message: 04/08/2004, 17h09

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