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 :

Afficher les champs et valeur d'un objet en surchargeant toString()


Sujet :

Java

  1. #1
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut Afficher les champs et valeur d'un objet en surchargeant toString()
    Bonjour, depuis un moment je cherchais à afficher l'état d'un objet en affichant la liste de ses champs et leur valeur en surchargeant la méthode toString() (ou en utilisant un autre nom de méthode).

    Je me suis penché sur le problème aujourd'hui, et j'en suis arrivé au code suivant. Je suis dans le cas où j'utilise des objets qui héritent d'une classe mère qui contient, elle, les attributs intéressants.

    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
    	@Override
    	public String toString() {
    		String thisName = this.getClass().getSuperclass().getName();
    		String objectName = thisName.substring(thisName.lastIndexOf("."), thisName.length());
     
    		StringBuffer buf = new StringBuffer();
    		buf.append("--- Object " + objectName + " Begin ----\n");
     
    		Field[] fields = this.getClass().getSuperclass().getDeclaredFields();
     
    		for (int index = 0; index < fields.length; index++) {
    			Field field = fields[index];
    			String value = null;
    			try {
    				Object obj = field.get(this);
    				if (obj != null)
    					value = (String) obj.toString();
    				else
    					value = null;
    			}
    			catch (IllegalArgumentException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			catch (IllegalAccessException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			if (value != null)
    				buf.append(field.getName() + ": " + value.toString() + "\n");
    			else
    				buf.append(field.getName() + ": NULL\n");
    		}
    		buf.append("--- Object " + objectName + " End ----\n");
     
    		return buf.toString();
    	}
    SI vous avez des suggestions pour améliorer ce code et le rendre encore plus générique (par exemple en allant chercher les attributs de l'objet courant si besoin, ou d'objet de classes supérieures), c'est pas de refus.

    En tout cas, cette portion de code est là pour ceux à qui elle conviendrait. Une fois le code optimisé, il pourrait être intéressant de l'ajouter à la FAQ ?

    Existe-t-il une méthode plus simple pour en arriver au même résultat ?

  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,


    toString() n'est pas trop adapté à cela je trouve...

    Sinon tu peux faire quelque chose d'encore plus générique avec l'introspection :
    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
    	public static void print(Object object) throws IntrospectionException {
    		String objectName = object.getClass().getSimpleName();
    		BeanInfo info = Introspector.getBeanInfo(object.getClass());
    		System.out.println("--- Object " + objectName + " Begin ----");
    		for (PropertyDescriptor property : info.getPropertyDescriptors()) {
    			String name = property.getDisplayName();
    			Object value = null;
    			try {
    				value = property.getReadMethod().invoke(object);
    			} catch (Exception e) {
    				value = "Erreur - " + e.getMessage();
    			}
    			System.out.println(name + ": " + value);
    		}
    		System.out.println("--- Object " + objectName + " End ----");
    	}
    Cela te récupère toutes les valeurs en utilisant les accesseurs

    a++

  3. #3
    Membre éclairé Avatar de Heimdal
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 549
    Points : 718
    Points
    718
    Par défaut
    Sinon tu peux utiliser la classe ToSringBuilder d'Apache commons-lang

  4. #4
    Membre expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Points : 3 675
    Points
    3 675
    Par défaut
    Citation Envoyé par Heimdal Voir le message
    Sinon tu peux utiliser la classe ToSringBuilder d'Apache commons-lang

    +1

    ça évite de se casser la tête...
    "Le plug gros problème des citations trouvées sur internet, c'est qu'on ne peut jamais garantir leur authenticité"

    Confucius, 448 av. J-C

  5. #5
    Membre régulier

    Inscrit en
    Novembre 2007
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 121
    Points : 104
    Points
    104
    Par défaut
    Eh bien, visiblement, je me suis compliqué la vie.

    Je regarderai ces deux propositions dés que possible, merci bien.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 18
    Points : 20
    Points
    20
    Par défaut toString
    Citation Envoyé par raf64flo Voir le message
    Eh bien, visiblement, je me suis compliqué la vie.

    Je regarderai ces deux propositions dés que possible, merci bien.
    Et bien merci de t'être compliqué la vie, car moi ça va me servir

    En fait j'ai un soucis avec BeanUtils.describe() et ToStringBuilder, ils tournent en rond vu mes objets métiers bidirectionnels (dossier<->client)

    Après pourquoi n'est-ce pas adapté a toString() ? J'ai plutôt l'impression du contraire (transformer un objet en String) ...

  7. #7
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    On a rarement besoin de tous les champs pour identifier un objet.

    - Ou bien il s'agit de logger des choses, auquel cas c'est à charge du codeur de savoir ce qu'il veut logger (et c'est très peu probablement toutes les propriétés de l'objet) ;

    - Ou bien c'est pour faciliter le mode debug, mais là encore pas vraiment besoin de voir toutes les propriétés, ça peut rapidement rendre illisible le toString.

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    18
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 18
    Points : 20
    Points
    20
    Par défaut Identifier ?
    Je n'utilise pas toString pour identifier un objet, mais plutot le getter de son id/numéro. Et le mode debug sert a loguer toutes les données en général, du moins dans les appli sur lesquels je bosse et dans les DAO. Sinon je vois pas trop l'intérêt de créer un toString restreint en fait, car comme tu dis si on veut juste quelques données il suffit de les loguer individuellement.

    Et pour ce qui est de ne pas rendre un toString illisible, j'ai finalement trouvé le ToStringBuilder vraiment bien une fois associé avec un ToStringStyle ! On peut dans ce cas formater les données désirées sans utiliser le toString des sous-objets via un test de la classe et l'utilisation du getter de l'id par exemple

    sources :
    http://commons.apache.org/lang/api/o...ngBuilder.html
    http://commons.apache.org/lang/api/o...ringStyle.html

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 23/04/2007, 13h37
  2. [CR] Ne pas afficher un champ de valeur nulle
    Par mavericks dans le forum SAP Crystal Reports
    Réponses: 4
    Dernier message: 28/03/2007, 16h06
  3. Re-afficher les champs que l'utilisateur à saisi
    Par Dsphinx dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 20/11/2006, 07h27
  4. Réponses: 5
    Dernier message: 25/10/2005, 16h05
  5. afficher les champs null de deux tables dans un select
    Par poil dans le forum Langage SQL
    Réponses: 2
    Dernier message: 27/09/2005, 15h05

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