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

Langage Java Discussion :

Paramètre avec un OU inclusif


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 106
    Par défaut Paramètre avec un OU inclusif
    Bonjour,

    J'ai récemment vu un code qui m'intrigue. Sur Android, lorsque l'on souhaite écouter des informations sur le téléphone, on appelle une méthode de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    mManager.listen(mListener, PhoneListener.LISTEN_CALL_STATE
    				| PhoneListener.LISTEN_SIGNAL_STRENGTH
    				| PhoneListener.LISTEN_DATA_CONNECTION_STATE
    				| PhoneListener.LISTEN_SERVICE_STATE
    				| PhoneListener.LISTEN_CELL_LOCATION);
    Chaque constante est un Integer allant de 1 à 4. Comment la méthode listen arrive à retrouver tout les éléments passés dans le deuxième paramètre ?

    En l’occurrence je passe :
    1 : 0001
    2 : 0010
    3 : 0011
    4 : 0100

    Ce qui me donne : 0111 soit 7 et à partir de ce nombre 7, je retrouve comment les 4 (ou plus, ou moins) éléments passés en paramètre ?

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int listenCallState = param & PhoneListener.LISTEN_CALL_STATE;
    boolean hasCallState = listenCallState  != 0;
    Pareil pour les autres. On appelle ça un champ de bits.

    En Java moderne, et à moins qu'on fasse ces appels toutes les millisecondes, on préférera définit un enum des paramètres possibles, et passer ceux qu'on veut à l'aide d'un EnumSet. C'est plus clair. Mais pas aussi rapide en calcul intensif.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 106
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int listenCallState = param & PhoneListener.LISTEN_CALL_STATE;
    boolean hasCallState = listenCallState  != 0;
    Pareil pour les autres. On appelle ça un champ de bits.

    En Java moderne, et à moins qu'on fasse ces appels toutes les millisecondes, on préférera définit un enum des paramètres possibles, et passer ceux qu'on veut à l'aide d'un EnumSet. C'est plus clair. Mais pas aussi rapide en calcul intensif.
    Si j'ai une constantes qui vaut 7, j'aurais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int listenCallState = 0111 & 0111;
    Ça va me retourner différent de 0 alors que je n'ai pas mis la constante 7 dans mes paramètres.

    A première vue c'est irréversible, je ne comprends pas son intérêt.

    Si j'ai service qui doit demander des ressources à un autre service (qui l'autorise ou non à utiliser ces ressources), je pensais utiliser ce type de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    final int DATA = 1;
    final int SCREEN = 2;
     
    Server server = Server.getInstance();
    boolean ack = server.ask(DATA | SCREEN);
    if (ack) {
        this.run();
    } else {
        this.stop;
    }
    Mais je vois pas comment interpréter le paramètre passé du coté serveur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public boolean ask(int resources) {
        ???
    }
    Je vais partir sur les enums je pense.

  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
    Salut,

    Citation Envoyé par FinalSpirit Voir le message
    Mais je vois pas comment interpréter le paramètre passé du coté serveur.
    Il faut faire l'opération avec & pour chaque valeurs à gérer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	public static void ask(int resources) {
    		if ( (resources & DATA) == DATA )
    			System.out.println("DATA");
     
    		if ( (resources & SCREEN) == SCREEN )
    			System.out.println("SCREEN");
    	}
    Bien sûr comme c'est du calcul bit à bit il faut que chaque valeur correspondent bien à un bit différent.



    Citation Envoyé par FinalSpirit Voir le message
    Je vais partir sur les enums je pense.
    Perso je trouve le choix de l'enum plus propre car cela rend le code plus lisible et plus clair, tout en limitant le risque d'erreur et en améliorant les logs...


    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
    	enum Resources {
    		DATA, SCREEN;
    	}
     
    	public static void ask(Resources...resources) {
    		for (Resources res : resources) {
    			switch(res) {
    			case DATA:
    				System.out.println("DATA");
    				break;
    			case SCREEN:
    				System.out.println("SCREEN");
    				break;
    			}
    		}
    	}

    a++

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par FinalSpirit Voir le message
    Si j'ai une constantes qui vaut 7, j'aurais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int listenCallState = 0111 & 0111;
    Ça va me retourner différent de 0 alors que je n'ai pas mis la constante 7 dans mes paramètres.
    Ouais mais le principe c'est que tu auras pas de constante qui vaut 7, en fait.
    Disons qu'une constante qui vaut 7, c'est un raccourci pour avoir la constante qui vaut 1, celle qui vaut 2, et celle qui vaut 4.
    Alors ça peut être passé en paramètre, oui, mais ça ne doit pas être utilisé pour décoder le paramètre. Il ne faut utiliser que les puissances de 2. Et comme c'est pas évident de faire la différence entre ce qui est une puissance de 2 et ce qui l'est pas, c'est pour ça qu'il vaut mieux ne pas définir de constante qui n'en soit pas, à côté de celles qui le sont.

    Citation Envoyé par FinalSpirit Voir le message
    Je vais partir sur les enums je pense.
    C'est mieux, oui. Sauf en cas de calcul intensif, ce qui n'est clairement pas le cas ici.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    L'enum, oui, si tu n'as qu'une seule valeur possible à la fois...
    mais sinon, avec les masques, on passe 1 paramètre où chaque bit représente une information à tester, c'est différent.

    d'ailleurs, les 2 exemples de code d'adiGuba avec l'enum ou les bits ne correspondent pas
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    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 OButterlin Voir le message
    d'ailleurs, les 2 exemples de code d'adiGuba avec l'enum ou les bits ne correspondent pas
    Dans mon exemple l'enum est couplé avec une ellipse, donc tu peux tout à fait en passer plusieurs (voir même aucune)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ask();
    ask(Resources.DATA);
    ask(Resources.SCREEN);
    ask(Resources.DATA, Resources.SCREEN);
    Il est possible de forcer l'utilisation d'au moins un paramètre via une signature comme celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static void ask(Resources mainResources, Resources... otherResources)



    La principale différence avec mon code sur les enums vient du fait qu'on peut passer plusieurs fois la même valeur (avec l'opérateur de bit cela disparait automatiquement). Mais bon si cela pose problème on peut y pallier facilement en utilisant un EnumSet...



    Mais les enums ont d'autres avantages :
    • Le code est fortement typé. On ne peut plus se tromper de valeur
    • Le type enum comporte bien plus d'information, et pourrait contenir plus d'information qu'un simple champ de bit.
    • On peut logguer facilement sans avoir à déchiffrer des valeurs numériques inconnues




    Il y a même moyen de coupler cela avec une interface pour avoir à la fois quelque chose de souple et d'évolutif (c'est que qui est utiliser dans l'API NIO.2 FileSystems de Java 7)


    a++

  8. #8
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    | opérateur binaire, regarde ceci tu auras des explications...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. Déterminer une requête paramétrée avec LIKE
    Par priest69 dans le forum Access
    Réponses: 4
    Dernier message: 24/10/2005, 19h29
  2. [Tableaux] passer un paramètre avec un popup
    Par lnikolanta dans le forum Langage
    Réponses: 6
    Dernier message: 11/10/2005, 16h36
  3. Réponses: 2
    Dernier message: 12/09/2005, 15h33
  4. Date nulle dans une requete paramétrée avec TParameter
    Par denrette dans le forum Bases de données
    Réponses: 3
    Dernier message: 16/06/2004, 08h37
  5. Récupération des paramètres avec une procedure stockée
    Par samlerouge dans le forum Bases de données
    Réponses: 2
    Dernier message: 31/03/2004, 22h00

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