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

Java Discussion :

Problème de variables globales / locales


Sujet :

Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 13
    Points : 10
    Points
    10
    Par défaut Problème de variables globales / locales
    Dans ma classe Appli, je me connecte à une BDD et je lance une requete SQL via la méthode envoiRequete(). Je récupère ensuite le nombre de lignes n qui vont être renvoyées par ma requête SQL. Puis je crée les tableaux id_event et nom de longueur n qui serviront à stocker le résultat de ma requête.
    Ainsi la longueur de mes tableaux est adaptée au nombre de lignes renvoyées par la requête.


    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
    import java.sql.*;
    class Appli
    {
      public Appli ()
        {
    	  envoiRequete ();
        }
      void envoiRequete()
      {
        try
          {
    	String nomDriver = "com.mysql.jdbc.Driver";
    	try
    		{
    		Class.forName(nomDriver); 
    		}
    	catch(ClassNotFoundException cnfe)
    		{
    		System.out.println("La classe "+nomDriver+" n'a pas été trouvée");
    		cnfe.printStackTrace();
    		}
    	Connection db;
    	ResultSet rs;
    	Statement s;
    	String requete;
    	
    	  {
    	    db = DriverManager.getConnection("jdbc:mysql://localhost:3306/freez?","hote","");
    	    s = db.createStatement ();
          /* -----------------------------------------
    	 Ici on utilise la méthode getPhrase de nos objets
    	 pour constituer une requete a la place de la requete 
    	 suivante :
    	 ----------------------------------------- */
    		requete = "SELECT * FROM event;";
    	    rs = s.executeQuery (requete);
    		int i = 0;
    		//Récupération du nombre de lignes du résultat
    		rs.last();
    		int n = rs.getRow();
    		System.out.println("\nResultat de la requete '"+requete+"' : ("+n+" entrees)");
             	//Création des tableaux à 1 dimension à n lignes
    		int id_event [] = new int [n];
    		String nom [] = new String [n];
    		//Remplissage des tableaux
    		do{
    		id_event [i]  = rs.getInt(1);
                    nom [i] = rs.getString(2);
    		i++;
    		}while (rs.previous());
    	    db.close ();
    	  }
          }
        catch (SQLException ex) 
          {
    	System.out.println("Exception: " + ex.toString());
    	ex.printStackTrace() ;
          }
      } /* envoiRequete */
      public static void main(String argv[])
        {
          new Appli ();
        }
    }
    Ce dont j'ai besoin : Récupérer ces tableaux dans une classe principale distincte. Or pour cela ces tableaux doivent être définis en variables globales et non locales, comme c'est présentement le cas.

    Là où ca coince : Si je définis mes tableaux en variables globales au début de la classe, je n'aurais pas encore récupéré le nombre de lignes n renvoyées par la requête SQL. Et je ne pourrais donc pas adapter la taille de mes tableaux lors de leur création. En effet je ne peux pas juste les définir au début de la classe, et préciser leur taille dans la méthode après avoir récupéré le nombre de lignes.

    NOTE : C'est une version simplifiée du problème, mais c'est très important pour moi de connaitre exactement le nombre de lignes que mes tableaux doivent avoir. J'applique un traitement assez lourd pour chaque ligne dans ma version longue...

    Idée : Si je pouvais forcer la définition d'une variable globale dans une méthode cela résoudrais mon problème et je n'aurais pas besoin de définir les tableaux avant la méthode. Mais c'est apparemment impossible...

    SVP, aidez-moi.

  2. #2
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    1. Les variables globales c'est le mal !
    2. Pour ton problème, je te conseille plutôt de renvoyer le tableau en retour de la méthode, ou carrément créer une classe qui contiendrais tous les résultats si tu as plusieurs tableaux à retourner.
    3. Enfin utilises des try/finally pour libérer tes ressources (voir la FAQ)



    a++

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 13
    Points : 10
    Points
    10
    Par défaut Merci
    Ok, donc on peut dires que tu gères! Je vais essayer, mais ta réponse me parait tout à fait judicieuse. Merci.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 13
    Points : 10
    Points
    10
    Par défaut Oui, mais...
    En fait y'a un truc qui va pas , c'est que ma méthode envoiRequete doit alors retourner 13 tableaux de types différents. Or une méthode ne peut retourner qu'un seul objet selon mes recherches... Donc je suis bloqué sur le même problème, comment faire pour passer mes variables locales (mes tableaux) à mon autre classe... ?

    Edit: J'avais pas vu la deuxième partie de ton message, mais là je vois pas trop comment faire pour retourner une classe... Je vais continuer à cherche , mais si tu as la réponse, je suis preneur.

  5. #5
    Membre confirmé Avatar de T`lash
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Saint-Pierre-Et-Miq.

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Septembre 2007
    Messages : 381
    Points : 519
    Points
    519
    Par défaut
    Tu peux renvoyer des ArrayList<Object>

  6. #6
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par onigami Voir le message
    En fait y'a un truc qui va pas , c'est que ma méthode envoiRequete doit alors retourner 13 tableaux de types différents. Or une méthode ne peut retourner qu'un seul objet selon mes recherches... Donc je suis bloqué sur le même problème, comment faire pour passer mes variables locales (mes tableaux) à mon autre classe... ?
    1. N'utilises pas de multiple tableau : c'est chaint à gérer et c'est source de problème.
    2. Tu te crées un objet représentant une ligne de ta table, c'est à dire comportant autant d'attributs que tu utilises de tableaux...
    3. Et ta méthode renverra simplement une liste de ton objet créé en 2.


    Bref faire de la POO et non pas du procédural !


    Un exemple :
    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
    /**
     * On crée un objet représentant les éléments de notre table.
     * Chaque instance représente une ligne de la table
     */
    class MonObject {
     
    	// Chaque attribut représente une colonne :
    	private int idEvent;
    	private String nom;
     
    	// Le constructeur initialise les différents champs 
    	public MonObject(int idEvent, String nom) {
    		this.idEvent = idEvent;
    		this.nom = nom;
    	}
     
    	public static List<MonObject> envoiRequete() {
    		// On crée la liste qui contiendra le résultat :
    		ArrayList<MonObject> arrayList = new ArrayList<MonObject>();
    		String driver = "com.mysql.jdbc.Driver";
    		try {
    			// On charge le driver :
    			Class.forName(driver);
     
    			// On récupère la connexion JDBC :
    			Connection con = DriverManager.getConnection(
    					"jdbc:mysql://localhost:3306/freez?", "hote", "");
    			try {
    				// On crée le statement :
    				Statement st = con.createStatement();
    				try {
    					// On exécute la requête et on récupère le ResultSet
    					String requete = "SELECT * FROM event;";
    					ResultSet rs = st.executeQuery(requete);
    					try {
    						while(rs.next()) {
    							// On récupère les valeurs :
    							int idEvent = rs.getInt(1);
    							String nom = rs.getString(2);
     
    							// Puis on ajoute l'objet dans la liste :
    							arrayList.add(new MonObject(idEvent, nom));
    						}
    					} finally {
    						rs.close();
    					}
    				} finally {
    					st.close();
    				}
    			} finally {
    				con.close();
    			}
    		} catch (SQLException ex) {
    			System.out.println("Exception: " + ex.toString());
    			ex.printStackTrace() ;
    		} catch (ClassNotFoundException cnfe) {
    			System.out.println("La classe "+driver+" n'a pas été trouvée");
    			cnfe.printStackTrace();
    		}
     
    		// On réduit l'arraylist au stricte minimum avant de la retourner :
    		arrayList.trimToSize();
    		return arrayList;
    	}
    }
    A noter qu'il existe plein d'API qui gère cela très bien...


    a++

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 13
    Points : 10
    Points
    10
    Par défaut Debriefing
    En fait j'ai passé la nuit dessus, j'ai aussi utilisé un arrayList que je retournai.
    Mais le traitement pour récupérer chaque élément dans le bon type est assez lourd et pas intelligent (je converti chaque ligne de l'arrayList en String, je split la chaine et je converti dans les tableaux les résultats.).

    Ton code est très propre, mais là je suis un peu fatigué et je viens de me faire cambrioler [y'a des jours où tout va mal], donc je vais peut être passer pour un nul mais je vois pas comment récupérer proprement le résultat dans ma classe principale? Et pour les types, l'arrayList est pas cool, car il ne garde pas les types mais concatènes les attributs dans une ligne.

    Si je récupère l'arrayList dans ma classe principale, je dois encore retraiter chaque ligne convertie en objet, pour ensuite retrouver le bon type.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    arrayListObject[] obj  = appli.envoiRequete().toArray();
    Et ca reste lourd....

    Désolé d'être un peut empoté, mais là je crois que la fatigue plus le stress... ca aide pas beaucoup.

  8. #8
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Désolé pour ton cambriolage



    Citation Envoyé par onigami Voir le message
    Et pour les types, l'arrayList est pas cool, car il ne garde pas les types mais concatènes les attributs dans une ligne.
    Je ne comprend pas ce que tu veux dire par là ! Une liste d'objet est surement plus simple à manipuler qu'une multitude de tableau...

    Citation Envoyé par onigami Voir le message
    Si je récupère l'arrayList dans ma classe principale, je dois encore retraiter chaque ligne convertie en objet, pour ensuite retrouver le bon type.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    arrayListObject[] obj  = appli.envoiRequete().toArray();
    Et ca reste lourd....
    Non pourquoi faire cela (encore un tableau !)
    Tu peux l'utiliser directement l'ArrayList, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    List<MonObject> list = appli.envoiRequete();
    for (MonObject object : list) {
        System.out.println ( object.getNom() );
    }
    (en aillant bien sûr implémenter proprement l'accesseur getNom() dans ta classe MonObject).


    Tu devrais replonger dans un cours de POO


    a++

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 13
    Points : 10
    Points
    10
    Par défaut Dernière question
    J'ai créé une méthode d'accès pour chaque attribut dans ma classe MonObject sur ce modèle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	public int getId_Event() {
    		return id_event;
    		}
    et lorsque je l'affiche avec la méthode suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        	List<MonObject> list = appli.envoiRequete();
        	for (MonObject object : list) {
        		System.out.println(object.getId_Event());
        	}
    toute la colonne est bien affichée, mais lorsque je veux récupérer le premier élément d'index 1 de ma colonne Id_Event dans une variable, impossible. J'ai essayé pas mal de choses en m'inspirant de la FAQ, des forums et de la javadoc, mais sans succès.
    J'ai du mal à comprendre le fonctionnement de ta boucle for :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(MonObject object : list)
    Je vois que ca parcourt la liste, mais après c'est abstrait dans ma tête.
    J'ai eu beau me documenter comme tu me l'a fort recommandé... j'ai pas compris ta syntaxe...

    PS: C'était une fausse alerte pour le cambriolage, l'alarme a bugé... C'est rare qu'un bug me fasse autant plaisir! ^^'

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 13
    Points : 10
    Points
    10
    Par défaut YESSS!!!!
    Ca y'est, j'ai trouvé, je savais bien qu'il fallait dormir pour trouver!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        public void recoi()
        {
        	List<MonObject> list = appli.envoiRequete();
        	int recup [] = new int [list.size()];
        	for (MonObject object : list) {
        		System.out.println(object.getId_Event());
        		recup [(object.getId_Event())-1] = (object.getId_Event());
        	}
        	System.out.println(recup[1]);
        }
    J'ai juste un peu modifié ta méthode, et ca marche!
    J'ai compris le fonctionnement de la boucle for et je l'ai adapté à mon cas.

    En tout cas merci pour ton aide qui m'a été précieuse!

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

Discussions similaires

  1. Problème sur Variable globale
    Par diamonds dans le forum Langage
    Réponses: 1
    Dernier message: 16/03/2007, 10h52
  2. Réponses: 4
    Dernier message: 04/02/2007, 19h39
  3. Réponses: 2
    Dernier message: 25/12/2006, 19h08
  4. Problème de variable globale
    Par Oberown dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 01/08/2006, 11h57
  5. Problème de variable globale
    Par Tournevyks dans le forum Général Python
    Réponses: 6
    Dernier message: 29/06/2006, 11h16

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