Bonjour,
J'écrivais un petit code de démonstration, et j'ai rencontré un obstacle inattendu.
Avec:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 public abstract class Fruit extends Produit implements Périssable {...} et public class Pomme extends Fruit {...}
J'ai écrit ceci:
La compilation échoue sur un message "The method add(P) in the type Vector<P> is not applicable for the arguments (Pomme)".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 public class Expérimentation { public <P extends Fruit> Vector<P> liste() { Vector<P> liste = new Vector<P>(); Pomme pomme = new Pomme("Pomme rouge"); liste.add(pomme); Fruit f = liste.get(0); return(liste); } }
Et pourtant, Pomme hérite bel et bien de Fruit!
Je peux essayer une grande variété d'instructions qui fonctionnent et qui le montrent:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Fruit f = liste.get(0); ou Vector<? extends Fruit> liste = new Vector<Pomme>();
Mais le add(pomme) dans le vecteur, lui, ne passe pas.
Bien entendu, si je modifie le prototype de ma fonction en:
et que j'adapte son code en conséquence, tout rentrera dans l'ordre. Mais:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 public Vector<Pomme> liste() ou public Vector<Fruit> liste()
- Ce n'est pas ce que je veux.
- Cela ne me donnera pas pour autant l'explication du problème de compilation qui se pose.
J'ai fait l'hypothèse que ce qui empêche Java de compiler mon programme c'est qu'à la compilation il procède au type erasure pour rendre son code binairement compatible 1.4.
Et qu'alors, il se dit:
Avec:
Avec:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 public Vector<Pomme> liste() je dois simuler cette invocation: Vector.add(Pomme p)
et dans les deux cas, je peux faire une assertion sur le paramètre d'entrée et le simplifier en un type unique.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 public Vector<Fruit> liste() je dois simuler cette invocation: Vector.add(Fruit f)
Mais avec:
Et là, je ne peux pas remplacer ? extends Fruit par une classe unique puisque cela pourrait être n'importe quelle classe dérivée de Fruit.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 public <P extends Fruit> Vector<P> liste() je dois invoquer: Vector.add(? extends Fruit f)
Mais cette explication ne me convient pas entièrement, car ? extends Fruit est une expression qui admet Fruit comme classe.
Donc, Java devrait pouvoir faire l'assertion que la méthode add(...) à appeler a pour prototype minimal garanti: Vector.add(Fruit f)?
Quel explication donnez-vous à ce qui se produit?
Je vous remercie!
Grunt.
Partager