C'est vrai, mais ils auraient pu renvoyer un tableau de type apparent T[]... (T[]) tab;Envoyé par adiGuba
On est sûr que tous les éléments sont de type T donc c pas génant...
C'est vrai, mais ils auraient pu renvoyer un tableau de type apparent T[]... (T[]) tab;Envoyé par adiGuba
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 :Envoyé par ®om
a++
Code : Sélectionner tout - Visualiser dans une fenêtre à part return new T[5];
Bah, oui, mais cette instruction, non:Envoyé par adiGuba
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...Envoyé par ®om
Si tu prend le code suivant :
Tu verras que tu obtiens une ClassCastException à l'execution...
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(); } }
Note toutefois que le compilateur te préviens en générant un warning sur l'instruction suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part (T[]) new Object[5]
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++
Ah ouais, étonnant, car ce code:
pourrait générer un warning à la compilation... Pourtant, ça n'est qu'à l'exécution que ça plante...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Object[] o = new Object[5]; String[] s = (String[]) o;
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.Envoyé par ®om
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 :
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 = uneMethodeQuiRenvoitUnTableau(); String[] s = (String[]) o;
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++
Surtout si on mélange Generics / non Generics (par exemple quand on fait du Swing qui n'est pas générique...)Envoyé par adiGuba
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...Envoyé par ®om
a++
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager