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 sur des collections


Sujet :

Langage Java

  1. #1
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut Generics sur des collections
    Bonjour à tous. Un petit pb de generics avec Java 1.5 (jdk 1.6 bridé) :

    Quelqu'un(e) sait-il(elle) pourquoi je ne peut pas écrire ceci, SVP ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (Class<List<Object>>) List.class
    ou
    ArrayList<Object>.class
    ou
    ArrayList<?>.class
    Eclipse le le compile pas.

    Pour contourner, j'ai écrit ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (Class<List<Object>>) new ArrayList<Object>().getClass()
    Qui compile sous Eclipse (bien sûr), mais pas sur le serveur IC, sous Maven...

    inconvertible types
    found : java.lang.Class<capture#297 of ? extends java.util.ArrayList>
    required: java.lang.Class<java.util.List<java.lang.Object>>
    Que dois-je faire, selon vous ?
    Merci d'avance.

  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,


    Ce comportement est normal puisque le typeage Generics est perdu après la compilation. Ce type de code n'est donc pas sûr, car il n'apporte aucune garantie sur le type exact de l'objet...

    Citation Envoyé par tooms4444 Voir le message
    Qui compile sous Eclipse (bien sûr), mais pas sur le serveur IC, sous Maven...
    Le compilateur standard javac n'accepte pas ceci !
    Si le compilateur d'eclipse le laisse passer, il émet quand même un warning, ce qui signifie que le code n'est pas sûr du tout.

    N'utilises pas ceci !


    Citation Envoyé par tooms4444 Voir le message
    Que dois-je faire, selon vous ?
    Il faudrait déjà savoir ce que tu cherches à faire exactement avec tout ceci...


    a++

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Les généric ne sont pas réifié en java pour le moment. Donc un Class<?> ne pourra jamais pointer vers un type générique précis. Autrement dit, dans la jvm Class<ArrayList> ça existe, mais Class<ArrayList<Machin>> ça n'existe pas!

    En effet, ça voudrais dire que je pourrais faire

    ArrayList<Machin> machins = laClass.newInstance(), hors tout ce que sortira newInstance c'st un ArrayList<?>, à vous de le caster pour le stocker dans un type précis.

    Les generics, ca ne concerne *que* le compilateur!

  4. #4
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    Ok. Je savais pour la réification ; je suis juste dans la compilation.

    J'étends une classe Javolution 5.5.1 avec le type paramétré List<Object>.
    et le constructeur de cette classe attend ce type précisément. Or, toutes mes tentatives échouent.

    Intuitivement, j'aurais écrit ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class ListFormat extends XMLFormat<List<Object>> {
     
    	public ListFormat() {
    		super((Class<List<Object>>) ArrayList.class);
    	}
     
    	@Override
    	public List<Object> newInstance(Class<List<Object>> cls, InputElement xml) throws XMLStreamException {
    		return new ArrayList<Object>();
    	}
    ...
    }
    Or même Eclipse ne veut rien savoir !

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    D'abord, ArrayList.class ne sera JAMAIS castable en List.class, donc déjà une erreur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class ListFormat extends XMLFormat<List<Object>> {
     
    	public ListFormat() {
                    // déjà, là, c'est moche
    		super((Class<List<Object>>) List.class);
    	}
     
    	@Override
    	public List<Object> newInstance(Class<List<Object>> cls, InputElement xml) throws XMLStreamException {
    		return new ArrayList<Object>();
    	}
    Mais au delà de ça, pour moi, le plus "propre" serait ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class MonArrayList extends ArrayList<Object>{}
    public class ListFormat extends XMLFormat<MonArrayList> {
     
    	public ListFormat() {
                    // déjà, là, c'est moche
    		super(MonArrayList.class);
    	}
     
    	@Override
    	public MonArrayList newInstance(Class<List<Object>> cls, InputElement xml) throws XMLStreamException {
    		return new MonArrayList();
    	}

  6. #6
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    D'abord, ArrayList.class ne sera JAMAIS castable en List.class, donc déjà une erreur.
    Ah, là, tu dis n'importe quoi... ce n'est PAS ce qui est écrit dans le constructeur.

  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
    Non, ce n'est pas un cast de ArrayList.class en List.class, c'est une correspondance entre ArrayList.class et Class<? extends List>.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    c'est pourtant ce que je lit moi
    (Class<List<Object>>) ArrayList.class

  9. #9
    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
    Citation Envoyé par tchize_ Voir le message
    c'est pourtant ce que je lit moi
    (Class<List<Object>>) ArrayList.class
    J'aurais dû être plus explicite (au moins citer à qui je répondais) : oui c'est bien ce que tooms a écrit, mais ce qui "marche depuis belle lurette" c'est que dans XMLFormat on a quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    getInstance(Class<? extends T> forClass)
    Cela dit, je viens de voir que le constructeur (protected) nécessite bel et bien la classe, et rien d'autre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    protected XMLFormat(Class<T> forClass)

  10. #10
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    Tout à fait... JE DIS N'IMPORTE QUOI, c'est officiel...
    dsl


    En fait, je suis juste paumé. POURQUOI on ne peut pas caster ArrayList.class en Class<ArrayList<Object>> ?????? Ni (donc) List.class en Class<List<Object>>, ce qui est mon point de départ. JUSTEMENT sachant que le byte code n'est pas réifié !

    Encore pardon pour la méprise de tout à l'heure. Je n'ai regardé que le code de ton message.

  11. #11
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut Si le pb n'a pas de solution, c'est qu'il n'y a pas de pb !
    Bon, OK. Alors voilà ce que j'ai finalement fait...

    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
     
    public class ListFormat extends XMLFormat<List<Object>> {
     
    	public ListFormat() {
    		super(null);	// Unbound ; cf. ExtendedBinding#getFormat
    	}
    ...
    }
     
    public class ExtendedBinding extends XMLBinding {
    ...
    	@Override
    	@SuppressWarnings("rawtypes")
    	protected XMLFormat getFormat(Class cls) {
    		if (List.class.isAssignableFrom(cls)) {
    			return new ListFormat();
    		}
     
    		try {
    			return super.getFormat(cls);
    		} catch (XMLStreamException e) {
    			e.printStackTrace();
    			return null;
    		}
    	}
     
    }
    Et là, ça M'EN bouche un coin, n'est-il pas ?

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    C'est un problème du au fait que List.class ne laisse pas de marge de manoeuvre.

    En fait, List.class retourn comme type Class<List> et non pas Class<List<?>>

    Pour le compilateur, ca fait une énorme différence. Car dans le premier cas, le type est fixé.

    On est d'accord que, vu l'absence de réification, concretement on a du List.class partout dans le constructeur et ça devrait pas poser problème.

    La seul solution que je vois pour caster c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Class<List<Object>> clazz = (Class<List<Object>>) ( (Class<?>)List.class);
    Mais c'est moche au possible à écrire

  13. #13
    Membre habitué
    Homme Profil pro
    Architecte senior Java EE/Spring - ScrumMaster
    Inscrit en
    Juin 2010
    Messages
    229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France

    Informations professionnelles :
    Activité : Architecte senior Java EE/Spring - ScrumMaster
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 229
    Points : 162
    Points
    162
    Par défaut
    Merci, tchize,

    Nous venons de faire un test de performances avec Javolution 5.5.1... HO MY F...G GOD !! C'est juste la CATASTROPHE !
    En plus, le bug que l'on espérait résoudre n'a pas bougé d'un iota...

    Du coup, retour à 5.3.1. Mais je garde tout ça quand même, c'est compatible.
    Merci A+

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

Discussions similaires

  1. Linq, Distinct et new sur des collections
    Par tfrancais dans le forum Linq
    Réponses: 1
    Dernier message: 01/09/2009, 09h32
  2. Réponses: 1
    Dernier message: 05/06/2009, 12h52
  3. [SP-2007] Déploiement d'un site modèle sur des collections différentes
    Par zoumar dans le forum SharePoint
    Réponses: 1
    Dernier message: 05/06/2009, 12h52
  4. Select et insert sur des collections
    Par layouni dans le forum PL/SQL
    Réponses: 3
    Dernier message: 19/08/2008, 14h52
  5. Réponses: 1
    Dernier message: 30/03/2008, 04h20

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