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 :

[generics] unchecked après un casting


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Par défaut [generics] unchecked après un casting
    J'ai le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    List<Dimension> list = (List<Dimension>)request.getSession()
       .getServletContext().getAttribute("dimensionsListApp");
    Compiler ce code m'affiche un warning, et comme je n'aime pas les warnings j'aimerais savoir comment le virer.
    Comme vous le savez l'objet request est un objet utilisé dans les servlets, je ne peux donc pas le modifier.
    L'ennui est que je ne peux pas vraiment faire autrement, il faut bien que je puisse récupérer mon objet se trouvant dans le scope application, mais comme il s'agit d'un template le compilateur fait la gueule.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    961
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 961
    Par défaut
    Pouvez-vous donner le texte du warning?

  3. #3
    Membre averti
    Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2005
    Messages
    17
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2005
    Messages : 17
    Par défaut
    Compiler ce code m'affiche un warning, et comme je n'aime pas les warnings j'aimerais savoir comment le virer.
    Bravo.

    Comme vous le savez l'objet request est un objet utilisé dans les servlets, je ne peux donc pas le modifier.
    Ca se discute.

    L'ennui est que je ne peux pas vraiment faire autrement, il faut bien que je puisse récupérer mon objet se trouvant dans le scope application, mais comme il s'agit d'un template le compilateur fait la gueule.
    Le compileur prévient que ton cast ne permet d'être sur uniquement que ton Object (renvoyé par getAttribute() ) est une List. Il ne peut pas s'assurer que c'est une List<Dimension> . Tu "risques" donc un ClassCastException (ce que les type génériques sont à la base censés éviter).
    C'est un problème avec les downcast génériques de Objects.
    Tu peux ajouter une annotation @SuppressWarnings, je ne vois pas d'autre solutions (a moins de 'wrapper' l'objet request dans un type a toi avec des bonnes méthodes de délégation, mais c'est un peu lourd peut etre).

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Par défaut
    C'est justement ce que je fais.
    Mais voila, il se trouve que les collections de types hétérogènes on en a besoin, ne serais-ce que pour ce cas précis. Je vais essayer avec SuppressWarning, mais c'est dommage que sun n'aie pas prévu un truc pour ca, ils ont vraiment choisi le chemin de la facilité avec leurs templates.

  5. #5
    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,


    Les Générics t'assures que le compilateur vérifiera pour quoi que ton code ne génère aucune ClassCastException lors de l'utilisation des classes Generics...

    Or ici ce n'est pas le cas. Si par erreur ta liste "dimensionsListApp" est une List<String> au lieu de List<Dimension>, tu n'auras pas d'erreur lors du cast (puisque à l'exécution on se retrouve avec une simple List), mais seulement lorsque tu utiliseras les méthodes génériques, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dimension d = list.get(0);
    Puisque l'élément renvoyé serait alors une String et non pas une Dimension...


    Pour éviter cela, tu es donc obliger d'utiliser @SuppressWarnings comme l'a indiqué defuse, afin d'indiquer au compilateur que tu sais qu'il y a un risque possible et que tu en prend la "responsabilité".


    Le plus simple dans ce cas est de se créer une méthode de cast qui ignorera ce warning :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        @SuppressWarnings("unchecked")
        public static <T> T forceCast(Object o) {
            return (T) o;
        }
    Que tu utiliseras comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            List<Dimension> list = forceCast( request.getSession()
                    .getServletContext().getAttribute("dimensionsListApp") );
    Bien entendu c'est à utiliser à tes risques et périls

    a++

    PS : Si tu n'as pas la dernière version de javac, il est possible que le compilateur ignore le @SuppressWarnings, dans ce cas il te restera seulement un warning...

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Par défaut
    C'est bien ce que je dis, les petits gars de sun ne se sont pas cassés pour implémenter les génériques. Ceux-ci ne sont gérés qu'au niveau du compilateur, le code à l'exécution ne change absolument pas. Pourtant il n'aurait pas été impensable de pouvoir tester à l'exécution qu'une List<String> n'est pas une List<Dimension>.
    Autre chose que je ne comprends vraiment pas: pourquoi est-il impossible de déclarer un tableau de génériques?
    Par exemple la ligne:
    Provoque non pas un warning mais une erreur, comment ca se fait-y?

  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 zais_ethael
    C'est bien ce que je dis, les petits gars de sun ne se sont pas cassés pour implémenter les génériques. Ceux-ci ne sont gérés qu'au niveau du compilateur, le code à l'exécution ne change absolument pas.
    Ce qui te garantit une compatibilité avec les JVM plus ancienne, et même d'utiliser des librairies plus ancienne avec ton code...

    Citation Envoyé par zais_ethael
    Pourtant il n'aurait pas été impensable de pouvoir tester à l'exécution qu'une List<String> n'est pas une List<Dimension>.
    Mais cela complique les choses... non seulement cela casse la compatibilitée (car dans ce cas une List ne serait pas une List<String>), mais cela augmente le nombre de classe chargé (puisqu'il faudra une classe par type de List par exemple). C'est le cas avec les templates du C++ et pour chaque type utilisé, tu as une nouvelle classe (avec copie du code, etc...), ce qui peut rendre le tout assez lourd...

    Bref si c'est fait comme cela ce n'est pas par facilité... de plus je te rappelle que les modifications de Java sont effectué en travail de groupe dans une JSP puis voté, par exemple pour les Generics : http://www.jcp.org/en/jsr/detail?id=14


    Citation Envoyé par zais_ethael
    Autre chose que je ne comprends vraiment pas: pourquoi est-il impossible de déclarer un tableau de génériques?
    Par exemple la ligne:
    Provoque non pas un warning mais une erreur, comment ca se fait-y?
    C'est la ligne suivante qui provoque une erreur (l'instanciation du tableau) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<String>[] list = new List<String>[10];
    En effet le type des générics est vérifié à la compilation, alors que celui des tableau l'est à l'exécution, de ce fait tu pourrais te retrouver dans certain cas où un élément de ton tableau n'est pas un List<String> sans avoir eu de warning ni d'erreur... et te retrouver avec un ClassCastException bizarre à l'exécution...

    Tu dois donc encore une fois supporter un warning à la compilation... même si le mieux serait d'utiliser des List imbriqué :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List<List<String>> list
    a++

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 02/07/2008, 15h04
  2. Cast d'une classe generic
    Par Seth77 dans le forum C#
    Réponses: 3
    Dernier message: 27/06/2008, 14h27
  3. Réponses: 2
    Dernier message: 25/04/2008, 10h43
  4. Erreur de cast sur les generics!
    Par Razgriz dans le forum Général Java
    Réponses: 8
    Dernier message: 02/10/2007, 18h33
  5. [JAVA 5.0] Generics - Cast et creation d'objets
    Par bourbaki2003 dans le forum Langage
    Réponses: 12
    Dernier message: 14/03/2007, 15h34

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