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 :

Le type variant en JAVA


Sujet :

Java

  1. #1
    Membre confirmé Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Par défaut Le type variant en JAVA
    Bonjour tout le monde,

    Je recherche un type en java qui peut être l'équivalant à variant en cpp. Dans recherches que j'ai faites beaucoup de personnes conseil Object mais le problème avec object c'est que les types primitifs sont convertie en object ( int => java.lang.Integer).
    Et de toute façon ça ne ressemble pas vraiment à variant car Object peut être tout et n'importe quoi (tout est objet) alors que variant peut accepter que certains types (par exemple, un std::variant<int,std::string,float> pourra contenir un int, ou un std::string, ou encore un float.).

    Si vous avez des pistes, avis ... je suis preneur

  2. #2
    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
    On pourrait "simuler" le comportement par une classe spéciale, un peu dans ce genre
    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
    package test.variant;
     
    public class Variant
    {
        private Class<Object>[] authorizedTypes;
        private Object value;
     
        public Variant(Class<Object>[] authorizedTypes)
        {
            super();
            this.authorizedTypes = authorizedTypes;
        }
     
        public Object getValue()
        {
            return value;
        }
     
        public void setValue(Object value) throws RuntimeException
        {
            if (value == null)
            {
                this.value = null;
                return;
            }
     
            boolean ok = false;
            for (Class cls : authorizedTypes)
            {
                if (value.getClass() == cls)
                {
                    ok = true;
                    break;
                }
            }
            if (ok)
            {
                this.value = value;
            }
            else
            {
                throw new RuntimeException("Type " + value.getClass() + " non autorisé");
            }
        }
     
        public Class getValueClass()
        {
            if (value == null)
            {
                return null;
            }
            return value.getClass();
        }
    }
    Mais bon, derrière la méthode getValue() il faudra faire un cast du type si besoin...
    J'ai fait un test comme ceci et ça fonctionne
    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
    package test.variant;
     
    public class TestVariant
    {
     
        public static void main(String[] args)
        {
            Variant v = new Variant(new Class[] {Integer.class, String.class});
     
            v.setValue(13);
            System.out.println(v.getValueClass() + " : "  + v.getValue());
     
            v.setValue("Un test");
            System.out.println(v.getValueClass() + " : "  + v.getValue());
     
            v.setValue(13.5); // <-- RuntimeException ici
            System.out.println(v.getValueClass() + " : "  + v.getValue());
        }
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre confirmé Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Par défaut
    Salut,
    Pas mal comme approche.
    Merci .
    Je vais étudier ça .

  4. #4
    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
    Je dirais que ce qu'il faut retenir, c'est que Java encourage à penser autrement que ce type variant de C++. Au fond, en quoi est-ce qu'il aide, véritablement ? A quoi sert-il ? Ben oui, c'est pas glorieux.



    Dès lors, le programmeur Java va en général se rabattre sur deux approches habituelles :

    - Juste utiliser un Object et regarder ensuite le type réél de l'objet dedans. Là c'est encore moins utile que variant, mais c'est au moins plus simple.

    Tu nous dis que les primitifs se retrouvent wrappés dans ce cas-là. Genre, comme si c'était un problème. Les primitifs sont wrappés... Et alors ? Variant ne fait pas mieux puisqu'il wrappe son contenu...

    - Construire une classe dédiée, mais qui est vraiment faite pour.

    Ca ressemblerait à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Construit un BonbonOuMalefice qui contient un Bonbon goût fraise
    BonbonOuMalefice prems = BonbonOuMalefice.deBonbon(Gout.FRAISE);
     
    // Construit un BonbonOuMalefice qui contient un maléfice sectumsempra avec les caractéristiques données.
    BonbonOuMalefice deuz = BonbonOuMalefice.deMalefice(new SectumSempra(Portee.LOIN, Force.FORT));
     
    if(prems.estUnBonbon()) {
      prems.leBonbon().manger();
    } else {
      MinistereMagie.porterPlaintePour(prems.leMalefice());
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre confirmé Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Par défaut
    Je sais que généralement, (voire tout le temps) en Java on n'a pas besoin de ce type. Mais je travaille actuellement sur du multi langages et le c++ m'envoie une variable de type variante qui est sérialisé en JSON.
    J'avais peur de la sérialisation ce fasse sur le type "variant" et qu'il fallait créer un objet similaire pour que la désérialisation se passe correctement. Mais finalement je pense que seule la valeur est sérialisée (int, float ...). Donc avec un Object simple le pour récupérer la valeur ça suffit largement.
    D'ailleurs question un peut différente vous est-il arriver de sérialiser une variable de type "byte" ? Car quand on la désérialise on récupère un String et plus un byte ? Une idée ? Je suppose que cela dépend du "Serializer"...

  6. #6
    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 Badshade23 Voir le message
    Je suppose que cela dépend du "Serializer"...
    Voilà.

    Personnellement je ne trouve pas grand intérêt aux bibliothèques de sérialisation prête à streamer que tout le monde utilise pourtant...

    Quand on lit des exemples, c'est impressionnant tellement c'est simple, et dès qu'on se retrouve dans un cas réel elles font tout sauf ce qu'on avait besoin de faire et on perd un temps abominable à créer un contournement horrible que personne ne comprend.

    Alors qu'avec du simple JDOM 2 ou json.org la solution est codée en vingt minutes chrono, élégante et évidente. Certes il a fallu écrire du code soi-même, et ce serait le cas même avec les exemples de Jackson ou gson où il n'y a pas besoin de coder. Mais quand on fait vraiment quelque chose Jackson ou gson imposent encore plus de coder, et bien plus difficilement.

    Conclusion, quand j'ai besoin de sérialiser une variable byte, c'est moi qui décide à quoi elle va ressembler quand elle est sérialisée, et pour que la variable byte devienne ça quand elle est sérialisée, je programme que la sérialisation fait ça. Zéro défaut.

    Plus exactement, je ne raisonne pas en termes de sérialisation, je réfléchis au format du message à échanger entre les deux acteurs.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre confirmé Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Par défaut
    Oui, je comprend totalement ton point de vue ! Mon problème moi c'est que j'utilise le protocole WAMP avec la bibliothèque Autobhan https://crossbar.io/autobahn/.
    Pour ça que je n'ai pas vraiment la main sur les sérializer. En réalité j'ai le choix entre ces 3 :
    (Code de la class NettyWebSocketClientHandler)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    private ISerializer initializeSerializer(String negotiatedSerializer) throws Exception {
            switch (negotiatedSerializer) {
                case CBORSerializer.NAME:
                    return new CBORSerializer();
                case JSONSerializer.NAME:
                    return new JSONSerializer();
                case MessagePackSerializer.NAME:
                    return new MessagePackSerializer();
                default:
                    throw new IllegalArgumentException("Unsupported serializer.");
            }
        }
    Mais bon en parcourant les différents forum j'ai cru comprendre que pas mal de personne avait ce problème ou le sérialisze transforme les bytes en String que ce sois à la désérialisation ou à la sérialisation ...

Discussions similaires

  1. Problème avec le type variant
    Par fabrice001 dans le forum C++Builder
    Réponses: 4
    Dernier message: 21/12/2005, 10h18
  2. comment faire un message de type "alert" en java
    Par fracam dans le forum Composants
    Réponses: 4
    Dernier message: 05/12/2005, 17h03
  3. locate - type variant incorrect
    Par lol_adele dans le forum Bases de données
    Réponses: 8
    Dernier message: 24/10/2005, 15h54
  4. [D2005] Type Variant en .NET
    Par Harry dans le forum Delphi .NET
    Réponses: 5
    Dernier message: 28/04/2005, 18h00
  5. Convertion de type VARIANT à type CString
    Par j_grue dans le forum MFC
    Réponses: 2
    Dernier message: 07/11/2002, 14h18

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