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

JSF Java Discussion :

Pré-remplir un <h:inputTextArea>


Sujet :

JSF Java

  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Par défaut Pré-remplir un <h:inputTextArea>
    Bonjour,

    Pour m'exercer sur JSF que je commence à peine à découvrir, j'essaie de refaire à la sauce JSF un projet codé avec JSP/servlets.

    Je bloque sur une des "fonctionnalités" qui était opérationnelle dans la version JSP/servlets : je dispose d'une Entity Member qui contient une liste de News. Lors de l'affichage de profil.xhtml, la liste de News est affichée. Si l'utilisateur connecté est le même que l'auteur des News, un lien d'édition est disponible pour chacune d'elle. Lors du clic sur un de ces liens, un modal Bootstrap avec un formulaire d'édition apparaît. Je veux que la zone de texte de ce formulaire soit pré-remplie avec le contenu actuel de la News.

    Auparavant, j'avais déjà essayé (sans succès) de remplir cette zone de texte avec le contenu d'un paragraphe donné (contenu de la news, repéré par son id) du coup j'avais généré le code du modal autant de fois que j'affichais une news (5 maximum) et je remplissais naturellement la textArea :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <c:forEach var="var" items="${requestScope.member.news}">
    [...] <!-- Code HTML non pertinent -->
    <textarea name="content" rows="5" maxlength="500" placeholder="Saisissez votre message ici"><c:out value="${var.content}"/></textarea>
    [...] <!-- Code HTML non pertinent -->
    </c:forEach>
    Désormais j'ai un bean NewsBean(RequestScoped) qui contient un attribut content. Du coup, je n'arrive pas à pré-remplir le composant <h:textArea> puisque sa valeur initiale est initialisée à celle de content (donc à null) ! Comme solution temporaire j'ai fait un formulaire presque HTML pur sucre mais ça m'oblige à récupérer les paramètres et les convertir... bref tout ce que JSF devrait me permettre de ne pas faire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <h:form>
            <textarea name="content" rows="5" maxlength="500" placeholder="Saisissez votre message ici" 
            	style="width:95%"><h:outputText value="#{var.content}"/></textarea>
    	<button type="button" class="btn btn-default pull-right" data-dismiss="modal">Fermer</button>
            <h:commandButton action="#{newsBean.edit}" value="Poster" styleClass="btn btn-primary pull-right"> 
            	<f:param name="id" value="#{var.id}" />
           </h:commandButton>
    </h:form>
    Y a-t-il un moyen de faire ça plus proprement avec JSF ? Merci d'avance !

  2. #2
    Traductrice
    Avatar de Mishulyna
    Femme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Bonjour,

    Je n'ai jamais utilisé JSP mais il me semble que vous devriez gérer ça par un @SessionBean MemberBean vue que ce n'est qu'un Member qui peut éditer ses propres News. Chaque Member aura sa Collection de News. Les hyperliens ou boutons pour l'édition des News d'un Membre pourront être accessibles via un renderer (news.author = memberBean.current).

  3. #3
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Par défaut
    Merci pour votre réponse.

    Petite précision : je n'utilise justement plus de JSP puisque je refais tout en mode JSF, donc la JSTL et les scriptlets ne sont plus d'aucune utilité.

    Par ailleurs, j'utilise bien un bean ConnectBean qui est SessionScoped mais la liste des news est un attribut LAZY de ma classe Member, donc l'attribut user de ConnectBean ne contient a priori pas ses News. C'est seulement lorsqu'un NewsBean est instancié que la liste des News est remontée (et l'objet user est mis à jour grâce à l'annotation @ManagedProperty qui me permet d'injecter user dans NewsBean).

    Maintenant admettons que j'ajoute un attribut current sur NewsBean, supposons qu'il soit égal à null. Je clique sur le bouton déclencheur du modal, il faut donc que current prenne la valeur de la news correspondante, mais comment faire ? Je n'ai pas réussi à passer de paramètre dans un appel de méthode via l'attribut action de commandLink.

  4. #4
    Traductrice
    Avatar de Mishulyna
    Femme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Quelles sont les fonctionnalités du ConnectBean? L'authentification d'un Member pourrait être gérée dans un MemberBean. Si ça ne vous gêne pas de montrer le code des beans...

  5. #5
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Par défaut
    Voilà ce que fait en substance ce que fait ConnectBean (peut-être un peu mal nommé d'ailleurs mais au début il ne faisait que d'authentifier l'utilisateur) :

    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
     
            // [...] @ManagedBean, @SessionScope, String constantes
            @EJB
    	private MemberManager manager;
     
    	private boolean connected = false;
    	private String login;
    	private String pswd;
    	private String newPswd;
    	private Member user;
     
    	public ConnectBean() { 
    		reset();
    	}
     
    	public void changeImage(String s) {
    		System.out.print("yohoho " + s.isEmpty() + "  " + s);
    	}
     
    	public void connect() {
    		Member m = manager.find(Member.class,login);
    		String msg;
    		FacesMessage.Severity sev;
     
    		if (m == null) {
    			msg    = loginMessage;
    			sev    = FacesMessage.SEVERITY_ERROR;
    		}
    		else if (connected = m.getPassword().equals(MemberManager.sha1(pswd))) {
    			msg    = connectedMessage;
    			user   = m;
    			sev    = FacesMessage.SEVERITY_INFO;
    		}
    		else {
    			msg    = pswdMessage;
    			sev    = FacesMessage.SEVERITY_ERROR;
    		}
     
    		FacesMessage message = new FacesMessage(sev,msg,null);
    		FacesContext.getCurrentInstance().addMessage(null, message);
    	}
     
    	public String disconnect() {
    		reset();
    		FacesMessage message = new FacesMessage(goodbyeMessage);
    		FacesContext.getCurrentInstance().addMessage(null, message);	
    		return Pages.connection;
    	}
     
    	public void changeAccess() {
    		manager.merge(user);
    	}
     
    	public void changePassword() {
    		String msg;
    		FacesMessage.Severity sev;
     
    		if (MemberManager.sha1(pswd).equals(user.getPassword())) {
    			msg    = successChangeMessage;
    			sev    = FacesMessage.SEVERITY_INFO;
    			user.setPassword(MemberManager.sha1(newPswd));
    			manager.merge(user);
    		} else {
    			msg    = failurePswdMessage;
    			sev    = FacesMessage.SEVERITY_ERROR;
    		}
     
    		FacesMessage message = new FacesMessage(sev,msg,null);
    		FacesContext.getCurrentInstance().addMessage(null, message);	
    	}
     
    	private void reset() {
    		login  =  null;
    		pswd  = null;
    		user = null;
    		connected = false;
    	}
     
           // [...] getters, setters
    A noter que newPswd est là car je n'ai pas réussi à faire la validation complète du formulaire de changement de mot de passe.

  6. #6
    Traductrice
    Avatar de Mishulyna
    Femme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Théoriquement, vous pourriez charger la liste des News de l'utilisateur lors de l'authentification
    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
    ...
    private List<News> memberNews= new ArrayList<News>();
    
    ...
    public void connect() {
    		Member m = manager.find(Member.class,login);
    		String msg;
    		FacesMessage.Severity sev;
     
    		if (m == null) {
    			//
    		}
    		else if (connected = m.getPassword().equals(MemberManager.sha1(pswd))) {
    			msg    = connectedMessage;
    			user   = m;
                            memberNews = user.getNewsList();
    			sev    = FacesMessage.SEVERITY_INFO;
    		}
    		else {
    			//
    		}
     
    		FacesMessage message = new FacesMessage(sev,msg,null);
    		FacesContext.getCurrentInstance().addMessage(null, message);
    	}
    J'ignore si c'est faisable ou pas, tout dépend de comment sont définies les relations entre les deux Entity, Member et News...

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par -Dici- Voir le message
    Désormais j'ai un bean NewsBean(RequestScoped) qui contient un attribut content. Du coup, je n'arrive pas à pré-remplir le composant <h:textArea> puisque sa valeur initiale est initialisée à celle de content (donc à null) !
    Elle est là l'erreur. Si tu veux que le textArea soit prérempli, il faut que la valeur vers laquelle il pointe contienne ce remplissage. JSF fonctionne très simplement: du bean vers le formulaire et du formulaire vers le bean. Il n'y a donc pas d'autre endroit que le bean où stocker des données. Le formulaire se charge de la mise en page. Le bean du contenu.

  8. #8
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Par défaut
    @Mishulyna et tchize :

    Pour commencer, merci pour vos réponses. Je peux effectivement charger la liste dès la connexion mais ça ne résout pas mon problème, j'ai juste parlé du caractère LAZY de la liste pour expliquer la séparation des beans ConnectBean et NewsBean. D'autre part, j'ai bien compris le bind bidirectionnel entre les beans et les formulaires de la vue en JSF.

    Pour être plus clair, le problème c'est que lorsque je charge la page de profil je ne sais pas a priori quelle news l'utilisateur voudra éditer ni même s'il voudra en éditer une. Par la suite, la fenêtre d'édition de news s'ouvrant avec Javascript sans retour vers le serveur, il m'est impossible dans la limite de mes connaissances de pré-remplir la zone de texte via le bean, c'est pour ça que je suis obligé d'écrire en dur le contenu dans une textArea classique et de traiter le formulaire à la main comme je le ferais dans une Servlet.

    A vrai dire puisque ça fonctionne comme ça je ne m'acharnerai pas beaucoup plus longtemps, je voulais juste savoir si JSF offrait une meilleure solution à ce problème. De plus, ce projet n'est qu'un test de découverte superficielle du framework pour le comparer à Spring (que je n'ai pas encore testé) et faire un choix pour un véritable projet qui m'attend...

    Je passe le sujet en résolu car il n'y a aucun besoin pressant, mais si ma nouvelle explication vous inspire je serai toujours intéressé d'avoir une opinion. Merci encore pour vos réponses.!

  9. #9
    Traductrice
    Avatar de Mishulyna
    Femme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Bonjour,

    Personnellement, je trouve que commencer à découvrir JSF en modifiant un ancien projet n'est pas le meilleur choix. Si vous disposez de la base de données en question: créez un nouveau projet Java Web avec comme choix du Framework JavaServer Faces. Si ce n'est pas le cas, créez votre propre base de données en local puis créez le projet.

    NetBeans dispose d'une fonctionnalité qui permet de générer les entity (Classe.java) à partir des tables de la base des données, puis les ejb (ClasseFacade.java), les jsf (ClasseController.java) et les pages .xhtml à partit des classes entity. Ce code généré n'est pas parfait, il faut le vérifier et le corriger surtout au niveau des classes entity car souvent les relations @ManyToOne, @OneToMany et @OneToOne sont erronées. Il faut également adapter les pages .xhtml à vos besoins car généralement les possibilités d'affichage sont très basiques.

    Si votre IDE vous propose les mêmes facilités c'est tant mieux. Mais en tout cas, moi je commencerais par écrire mon propre code plutôt que de modifier un code existant, surtout si rien ne m'y oblige.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par -Dici- Voir le message
    Par la suite, la fenêtre d'édition de news s'ouvrant avec Javascript sans retour vers le serveur
    Comment tu faisait, avant, pour savoir ce que tu allais mettre en pré-remplissage alors, si il n'y a pas de communication avec le serveur??? Pour moi le problème est le même, en JSP non plus tu ne pouvais pas remplir...

    Sinon, si le but est d'afficher un formulaire d'édition suite au clic sur un bouton editer d'un ligne, je vois deux grandes manières de faire:

    1) tout faire coté client: tu as un formulaire vierge qui deviens soudain visible, et le javascript se charge de le pré-remplir avec les données de la ligne
    2) Tu fais un aller-retour vers le serveur qui pré-rempli le formulaire via son bean. JSF 2 supporte l'ajax, donc tu peux demander à ne rafraichir que la zone du formulaire.

  11. #11
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Par défaut
    @Mishulyna : Je reconnais que ce n'est pas forcément une bonne idée car la façon dont j'ai résolu des problèmes oriente trop ma façon de penser et ne me pousse pas assez à penser JSF. Cela dit, ça me permet d'avancer très vite (aucun code métier à écrire, peu de vue car mes pages JSP sont très facilement traductibles en xhtml) et de me confronter à différents problèmes, par contre je réécris bien sûr de 0 tout le code du contrôleur, je ne repars certainement pas du code des servlets.

    @tchize : j'ai effectivement essayé en Javascript mais comme je ne sais que reprendre du code existant et de l'ajuster à mes besoins ou bien d'utiliser des composants tout faits, je n'ai pas réussi ! De plus JSF renomme les id de mes composants, ce qui ne me facilite pas la tâche (même si je pense qu'il y a une parade simple quand on connaît bien Javascript).

    Je suis aussi intéressé par la possibilité de le faire en Ajax, c'est d'ailleurs ça qui m'intéresse le plus, car je sais que les composants JSF embarquent un peu d'Ajax, donc est-ce qu'il faut que j'écrive moi-même ce code ou les composants peuvent-ils le faire pour moi ? Pour l'instant je n'ai utilisé l'Ajax via les composants JSF que pour la validation de données, et je ne suis pas très au clair dessus dès que c'est plus compliqué qu'un simple champ sans relation avec les autres à valider.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par -Dici- Voir le message
    De plus JSF renomme les id de mes composants, ce qui ne me facilite pas la tâche (même si je pense qu'il y a une parade simple quand on connaît bien Javascript).
    Les ids sont tout à fait prévisibles en JSF: c'est view:parent:enfant:petit-enfant:.....:toniddecomposant Donc normalemet, si t'as bien mis des ids partout, il ne changera plus.

    Citation Envoyé par -Dici- Voir le message
    donc est-ce qu'il faut que j'écrive moi-même ce code ou les composants peuvent-ils le faire pour moi ?
    C'est géré en base. Commencer par faire un formulaire qui resoumet à chaque fois l'entièreté lorsqu'on sélectionne une ligne, ensuite t'aura juste 2/3 paramètres à ajouter sur le bouton pour 'ajaxifier' la requête

  13. #13
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Par défaut
    Pour les id, il m'ajoute des choses du genre j_idt23 en tête et ce n'est pas toujours le même nombre donc je ne sais pas comment prévoir ça (à moins que tu désignes par view l'id du noeud courant dans l'arbre des composants, auquel cas je regarderai comment il se récupère).

    Sinon merci, je suis finalement retourné sur la question avec de l'Ajax et c'est passé. Résolu pour de bon donc !

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par -Dici- Voir le message
    Pour les id, il m'ajoute des choses du genre j_idt23 en tête
    C'est que tu n'a pas donné d'id à certains de tes composant JSF dans la hierarchie. Le h:form a bien un id? Tous ses enfant aussi?

  15. #15
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Par défaut
    Effectivement seuls certains composants ont des id. Du coup j'imagine que ça signifie que JSF donne un id à tous les composants JSF qui n'en ont pas reçu, mais qu'autrement il les laisse tel quel (à part qu'il rajoute en tête la liste des parents séparés par ":"). Je le saurai à l'avenir encore une information précieuse, merci

    Sinon un truc qui n'a rien à voir mais j'ose pas créer un sujet pour ça c'est une broutille : je participe à d'autres forums sur Java et j'ai affirmé vigoureusement à quelqu'un que l'erreur dans son code provenait d'une comparaison de String avec ==, il me maintenait que non et je répondais que si. N'y tenant plus, j'ai testé par moi-même et j'ai été éberlué de voir que ça fonctionne effectivement avec la version actuelle de Java. J'ai cherché depuis quand c'était le cas mais je n'ai trouvé que la date de release du switch sur les String, qui est arrivé avec JDK 7. Une idée de quand ça date, parce que je pense qu'il est encore trop tôt pour l'utiliser en étant sûr que n'importe qui aura une version de Java assez à jour ?

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    une comparaison de Strings avec == marche "parfois", c'est à dire quand les deux cotés sont la même instance. C'est pour ça qu'il ne faut pas l'utiliser

    PS: je parle du principe que tu parle de code java, pas d'EL jsf.

  17. #17
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Par défaut
    Arg tu me fais mal là, je suis peut-être encore débutant sur JSF mais je sais bien qu'en Java == compare par référence et non par valeur ! A vrai dire c'est une des premières choses que j'ai apprise en Java en voyant que mon code tout simple bugait, c'était il y a 2 ans.

    Pour la petite histoire, j'ai dit ironiquement à la personne du topic d'exécuter ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class VersionJava {
         public static void main(String[] args) {
               String s = "test";
               String s1 = "test";
               if (s == s1)
                   System.out.println("JDK du futur");
               else if (s.equals(s1))
                   System.out.println("JDK 7 ou inférieur");
               else
                   System.out.println("Aucun JDK");
         }
    }
    Il me dit que ça lui sort "JDK du futur" et après test moi aussi alors que j'étais persuadé que le test échouerait dans ce cas. Tout mon système de valeurs a failli s'effondrer et j'étais prêt à dire adieu à la vie, mais en testant le code suivant le monde s'est remis à l'endroit (j'obtiens true puis false).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class VersionJava {
         public static void main(String[] args) {
               String s  = "test";
               String s1 = "test";
     
               System.out.println(s == s1);
               s1 += "coucou";
               s  += "coucou";
               System.out.println(s == s1);          
         }
    }
    Ca doit vouloir dire que lors de l'initialisation ou d'une affection où la valeur affectée est une chaîne en dur si la JVM voit une autre chaîne de caractères comportant les mêmes caractères elle donne la même référence mais dès qu'on fait une modification sur l'une, une copie est créée et == devient faux. Ca doit être une optimisation de la mémoire pour éviter les doublons lors de l'utilisation de chaînes constantes identiques ou de variables temporaires. C'est ce fonctionnement que je connaissais pas, mais te je rassure le fonctionnement de == je l'ai compris depuis un moment.

    Du coup lui dans son code il comparait des chaînes de caractères fixes (actionCommand de deux JButton) alors peut-être que c'est légèrement mieux de faire avec == pour la mémoire et la vitesse des comparaison (je crois pas me tromper en disant que == est plus rapide que equals das le cas général) mais je trouve qu'il faut avoir le goût du risque... Bref ce n'était qu'une parenthèse désormais fermée !

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Ben sans plus de détails, c'est tout ce que je pouvais te dire (et te confirmer que java n'a pas changé à ce sujet).

    Il faut juste savoir que les chaines constantes, dans la jvm, il est garantis que si deux chaines litérales sont égale, alors elles auront la même instance.

    Pour mieux comprendre, disons que la JVM interprète ton code en réalité comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class VersionJava {
         public static void main(String[] args) {
               String s  = "test".intern();
               String s1 = "test".intern(); // <-- même instance que s 
     
               System.out.println(s == s1);
               s1 = new StringBuilder(s1).append("coucou").toString(); //<-- new string
               s  = new StringBuilder(s).append("coucou").toString(); //<-- new string
               System.out.println(s == s1);          
         }
    }

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par -Dici- Voir le message
    alors peut-être que c'est légèrement mieux de faire avec == pour la mémoire et la vitesse des comparaison (je crois pas me tromper en disant que == est plus rapide que equals das le cas général) mais je trouve qu'il faut avoir le goût du risque... Bref ce n'était qu'une parenthèse désormais fermée !
    Oui, faut avoir le gout du risque (en tout cas être sur de ce qu'on fait) et non, ce n'est pas vraiment plus rapide, puisque la méthode equals dans String commence comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
    donc fait exactement la même chose ^^
    Si tu ramène derrière les optimisation du compilateur JIT qui peux sortir le code d'une méthode pour l'amener directement dans l'appelant pour éviter un appel de méthode, sur les points critiques, tu ne gagne rien.

    Si on est pas sur un code critique, le fait de ne pas appeler de méthode, c'est un peu comme lancer un caillou sur une mongolfière ou qu'elle aille plus vite. On ne peux pas dire que ça ne fait rien, mais l'effet est en deça de ce qu'on peux mesurer

  20. #20
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2014
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 57
    Par défaut
    Je suis allé voir la doc sur intern() et ça a éclairé ma lanterne à ce sujet ! Merci bien, un peu de culture ne fait pas de mal.

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

Discussions similaires

  1. remplir des tables a partir de fichiers TXT
    Par jeremie dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 10/03/2004, 14h50
  2. BCB6 => Remplir un ListView
    Par totofweb dans le forum C++Builder
    Réponses: 6
    Dernier message: 25/02/2004, 15h12
  3. remplir feuille excel
    Par thibaud60 dans le forum Access
    Réponses: 2
    Dernier message: 24/11/2003, 10h21
  4. [VB.NET] Créer et remplir un nouveau fichier Access
    Par Manue.35 dans le forum Accès aux données
    Réponses: 2
    Dernier message: 18/07/2003, 15h42
  5. [TChart] comment remplir un histogramme avec du rouge strié.
    Par :GREG: dans le forum Composants VCL
    Réponses: 2
    Dernier message: 12/08/2002, 09h37

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