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

Collection et Stream Java Discussion :

[algorythmie] remplir un tableau dont on ne connait pas encore la taille


Sujet :

Collection et Stream Java

  1. #21
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par adiGuba
    Mais il est impossible de connaitre le type paramétré puisqu'il est perdu : donc c'est impossible.


    Non : tu connais juste T mais pas son type exact. Or c'est ce dont tu as besoin pour créer un tableau.

    Le code suivant ne compile pas parce qu'il est impossible de connaitre le type exacte de T à l'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Test<T> {
        public T[] toArray() {
            return new T[5];
        }
    }
    a++
    C'est vrai, mais ils auraient pu renvoyer un tableau de type apparent T[]... (T[]) tab;

    On est sûr que tous les éléments sont de type T donc c pas génant...

  2. #22
    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
    Citation Envoyé par ®om
    On est sûr que tous les éléments sont de type T donc c pas génant...
    Sauf que comme on ne connait pas le type exact de T, on ne peut pas instancier de tableau de T et l'instruction suivante provoque une erreur :
    a++

  3. #23
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par adiGuba
    Sauf que comme on ne connait pas le type exact de T, on ne peut pas instancier de tableau de T et l'instruction suivante provoque une erreur :
    a++
    Bah, oui, mais cette instruction, non:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    T[] tab = (T[]) new Object[5];

  4. #24
    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
    Citation Envoyé par ®om
    Bah, oui, mais cette instruction, non:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    T[] tab = (T[]) new Object[5];
    Non car le type des tableaux est vérifié à l'exécution. Et qu'un Object[] ne peut pas être casté en String[] par exemple...

    Si tu prend le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Test<T> {
        public T[] toArray() {
            return (T[]) new Object[5];
        }
     
        public static void main(String[] args) {
            Test<String> test = new Test<String>();
     
            String[] strings = test.toArray();
        }
    }
    Tu verras que tu obtiens une ClassCastException à l'execution...

    Note toutefois que le compilateur te préviens en générant un warning sur l'instruction suivante :

    La seule solution pour renvoyer un tableau du bon type est d'avoir un objet Class du bon type, par exemple :
    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
    class Test<T> {
        private final Class<T> type;
     
        public Test(Class<T> type) {
            assert type!=null;
            this.type = type;
        }
     
        @SuppressWarnings("unchecked")
        public T[] toArray() {
            return (T[]) Array.newInstance(this.type, 5);
        }
     
        public static void main(String[] args) {
            Test<String> test = new Test<String>(String.class);
     
            String[] strings = test.toArray();
        }
    }

    a++

  5. #25
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Ah ouais, étonnant, car ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] o = new Object[5];
    String[] s = (String[]) o;
    pourrait générer un warning à la compilation... Pourtant, ça n'est qu'à l'exécution que ça plante...

  6. #26
    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
    Citation Envoyé par ®om
    Ah ouais, étonnant, car ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] o = new Object[5];
    String[] s = (String[]) o;
    pourrait générer un warning à la compilation... Pourtant, ça n'est qu'à l'exécution que ça plante...
    C'est "normal" : les tableaux possèdent une notion d'héritage (String[] hérite de Object[]) qui fait que la vérification ne peut être effectué qu'à l'exécution.

    Il n'y a pas de warning car l'utilisation des casts est par nature non-sécurisé et peut potentiellement provoquer une ClassCastException à l'exécution. Ton exemple est toutefois un cas simple qu'un outil de vérification de code pourrait détecter... mais ce n'est pas toujours aussi simple, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] o = uneMethodeQuiRenvoitUnTableau();
    String[] s = (String[]) o;
    Car dans ce cas on ne peut pas prédir d'éventuelle erreur cast sans analyser le code de la méthode, car si le vrai type du tableau est String[] cela fonctionnera. Le code suivant ne pose pas de problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Object[] o = new String[5];
    String[] s = (String[]) o;




    A l'inverse les Generics sont sécurisé et provoqueront plusieurs warnings/erreurs pour éviter ce type de problème : un code qui utilise les Generics ne devrait pas provoquer de ClassCastException s'il compile sans erreur ni warning...

    Par contre un warning sur l'utilisation des Generics peut impliquer l'apparition de ClassCastException plus loin dans le code !!!!

    D'ailleur les Generics apportent tellement de nouveaux warnings qu'il est parfois impossible de compiler un code 100% sécurisé sans warning si on n'utilise pas l'annotation @SuppressWarning...

    a++

  7. #27
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par adiGuba
    D'ailleur les Generics apportent tellement de nouveaux warnings qu'il est parfois impossible de compiler un code 100% sécurisé sans warning si on n'utilise pas l'annotation @SuppressWarning...
    Surtout si on mélange Generics / non Generics (par exemple quand on fait du Swing qui n'est pas générique...)

  8. #28
    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
    Citation Envoyé par ®om
    Surtout si on mélange Generics / non Generics (par exemple quand on fait du Swing qui n'est pas générique...)
    En effet... mais il faut quand même rester prudent, bien comprendre la raison du warning, et limiter au minimum sa portée avant d'utiliser l'annotation @SuppressWarning...

    a++

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Accéder à un tableau dont on ne connait pas le nom
    Par c.piette dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 06/05/2015, 07h33
  2. Réponses: 0
    Dernier message: 03/04/2014, 23h45
  3. Tableau simple dont on ne connait pas la taille
    Par Wells dans le forum VB.NET
    Réponses: 3
    Dernier message: 04/10/2007, 16h49
  4. Réponses: 6
    Dernier message: 06/09/2006, 21h28
  5. Réponses: 1
    Dernier message: 03/04/2006, 00h51

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