generics : besoin d'aspirine :D [Résolu]

generics : besoin d'aspirine :D [Résolu] - Java - Programmation

Marsh Posté le 17-01-2005 à 16:31:42    

Bon voilà, en tripatouillant les generics, j'arrive à une erreur de compil que je ne comprends pas. J'ai simplifier le problème pour essayer de mieux le comprendre. Mais je comprends toujours pas. Si quelqu'un de motivé veux s'amuser avec ça et me donner un indice :
 
EDIT : j'ai réécris le code de manière plus explicite deux messages plus bas ...
 

Code :
  1. public class TestA<B> {
  2.     B b;
  3.     TestD<TestC<B>> d;
  4.    
  5.     public <T,C extends TestC<B>> T plop(TestE<T,B,C> e) {
  6.         //  The method plop(B, C) in the type TestGenerics.TestE<T,C,B> is not  
  7.         // applicable for the arguments (B, TestGenerics.TestC<B> )
  8.         return e.plop(b,d.getC());
  9.     }
  10. }
  11. public class TestC<B> {
  12. }
  13. public class TestD<C extends TestC> {
  14.     public C getC() {
  15.         return null;
  16.     }
  17. }
  18. public interface TestE<T,B,C extends TestC<B>> {
  19.     public T plop(B b,C c);
  20. }


 
L'erreur balancée par eclipse :  
The method plop(B, C) in the type TestGenerics.TestE<T,C,B> is not applicable for the arguments (B, TestGenerics.TestC<B> ).
 
C'est ptet tout con, mais là j'y vois plus grand chose !


Message édité par bobuse le 19-01-2005 à 21:18:26

---------------
get amaroK plugin
Reply

Marsh Posté le 17-01-2005 à 16:31:42   

Reply

Marsh Posté le 17-01-2005 à 16:45:14    

bobuse : tout est en vrac, tu es sûr que c'est le code exact que tu as compilé ?
 
Puis avec des noms un peu plus réaliste ça serait plus facile à démerder.

Reply

Marsh Posté le 17-01-2005 à 16:56:41    

nraynaud a écrit :

bobuse : tout est en vrac, tu es sûr que c'est le code exact que tu as compilé ?


oui oui, c'est exactement pareil, j'ai la même erreur !
 

nraynaud a écrit :


Puis avec des noms un peu plus réaliste ça serait plus facile à démerder.


ouaip, je vais arranger ça ...


---------------
get amaroK plugin
Reply

Marsh Posté le 17-01-2005 à 17:17:28    

Bon alors voilà, je repose mon pb.
J'ai une classe Position dont le contenu importe peu :

Code :
  1. public class Position {
  2.     // ...
  3. }


 
 
Et le reste de mon code qui donne l'erreur :

Code :
  1. // première solution : une erreur de compilation
  2. public class Fish1<P extends Position> {
  3.     P pos;
  4.     Population1<Environment1<P>> pop;
  5.    
  6.     public final void move() {
  7.         P destination=null;
  8.         this.pop.getE().moveFish(this,destination);
  9.     }
  10.     public <T,E extends Environment1<P>> T plop(PerceptionInterface1<T,P,E> perceptionInterface) {
  11.         // The method percept(P, E) in the type TestGenerics.PerceptionInterface1<T,P,E> is not  
  12.         //  applicable for the arguments (P, TestGenerics.Environment1<P> )
  13.         return perceptionInterface.percept(pos,pop.getE());
  14.     }
  15. }
  16. public abstract class Environment1<P extends Position> {
  17.     public abstract void moveFish(Fish1<P> f,P p);
  18. }
  19. public class Population1<E extends Environment1> {
  20.     public E getE() {
  21.         return null;
  22.     }
  23. }
  24. public interface PerceptionInterface1<T,P extends Position,E extends Environment1<P>> {
  25.     public T percept(P b,E e);
  26. }


 
Pour la petite histoire, ce code lui compile sans erreur. Mais déclenche un warning que je me suis dit "ça serait bien de pas avoir de warning".

Code :
  1. // deuxième solution : un warning
  2. public class Fish2<P extends Position> {
  3.     P pos;
  4.     Population2<? extends Environment2> pop;
  5.    
  6.     public void plop1() {
  7.         P destination=null;
  8.         // Type safety: The method moveFish(TestGenerics.Fish2, TestGenerics.Position) belongs to
  9.         //  the raw type TestGenerics.Environment2. References to generic type  
  10.         //  TestGenerics.Environment2<P> should be parameterized
  11.         pop.getE().moveFish(this,destination);
  12.     }
  13.     public <T,E extends Environment2> T plop2(PerceptionInterface2<T,P,E> e) {
  14.         return e.percept(pos,pop.getE());
  15.     }
  16. }
  17. public abstract class Environment2<P extends Position> {
  18.     public abstract void moveFish(Fish2<P> f,P p);
  19. }
  20. public class Population2<E extends Environment2> {
  21.     public E getE() {
  22.         return null;
  23.     }
  24. }
  25. public interface PerceptionInterface2<T,P extends Position,E extends Environment2<P>> {
  26.     public T percept(P b,E e);
  27. }


 
Donc je peux laisser ce dernier code qui ne déclenche qu'un warning, mais :
 1 - sans warnings, c'est mieux
 2 - je comprends pas pourquoi l'autre code compile pas et j'aimerai bien savoir pourquoi !


Message édité par bobuse le 17-01-2005 à 17:23:27

---------------
get amaroK plugin
Reply

Marsh Posté le 17-01-2005 à 17:20:45    

bobuse > pas trop le temps de faire un paté, mais je psenque que c'est  

Code :
  1. public class TestA<B> {
  2.     B b;
  3.     TestD<TestC<B>> d;
  4.    
  5.     public <T,C extends TestC<B>> T plop(TestE<T,B,TestC<B>> e) {


 
que tu cherches à faire.
 
relance-moi ce soir si tu veux une explication (et que je fais pas un boulot-métro-dodo)

Reply

Marsh Posté le 17-01-2005 à 17:27:31    

nraynaud a écrit :

bobuse > pas trop le temps de faire un paté, mais je psenque que c'est  

Code :
  1. public class TestA<B> {
  2.     B b;
  3.     TestD<TestC<B>> d;
  4.    
  5.     public <T,C extends TestC<B>> T plop(TestE<T,B,TestC<B>> e) {


 
que tu cherches à faire.
 
relance-moi ce soir si tu veux une explication (et que je fais pas un boulot-métro-dodo)


Ha ouais mince, ça marche.
Heu oui, c'est vrai que mon "C extends TestC<B>" sert à rien ...
 
dur dur le lundi
 
n'empêche que je comprends pas quand même le message d'erreur, pas plus que pourquoi mon code n'était pas bon, mais bizarre je l'admets :D !
 
merci


---------------
get amaroK plugin
Reply

Marsh Posté le 17-01-2005 à 18:03:17    

en fait ça doit aussi marcher en mettant super à la place de "extends" dans le template de la méthode :

Code :
  1. public class TestA<B> { 
  2.     B b; 
  3.     TestD<TestC<B>> d; 
  4.      
  5.     public <T,C super TestC<B>> T plop(TestE<T,B,C> e) {

Reply

Marsh Posté le 17-01-2005 à 18:05:11    

Heu ouais, mais ça me conviens pas du tout :D
Moi je veux pouvoir passer des sous-types ;)
 
EDIT : et encore une fois, il sert à rien ton générique : tu l'utilises pas !
EDIT2 : oups, lu trop vite -> mal lu :D


Message édité par bobuse le 17-01-2005 à 18:22:38

---------------
get amaroK plugin
Reply

Marsh Posté le 17-01-2005 à 18:19:56    

héhéhé, réponse de débutant ...
 
réfléchis bien, tu verras que tu pourras encore passer les sous-types.

Reply

Marsh Posté le 17-01-2005 à 18:26:07    

des sous-types de TestE, ok, mais des sous-types de TestE qui sont paramétrés par un sous-type de TestC<B>, j'ai du mal à le croire ...


---------------
get amaroK plugin
Reply

Marsh Posté le 17-01-2005 à 18:26:07   

Reply

Marsh Posté le 17-01-2005 à 21:13:21    

en fait si tu mets super comme je te le propose dernièrement, tu vas pouvoir passer en paramètre de plop() des perceptionInterface qui sont beaucoup plus ouverts que les tiens. C'est assez fin.
 
prenons comme exemple les Collections.
 
imaginons que tu bosses sur des arborescences de fichiers.
 
tu as une classe abstraite DirectoryEntry avec comme sous-classe File et Directory.
 
tu as dans Directory, par exemple, une méthode qui va collecter les fichiers texte récursivement. Comme t'es pas con, tu fais du récursif.
 
tu fais donc une méthode dans Directory :

Code :
  1. public Collection<File> getTxtFiles() {
  2.   Collection<File> macollec = ...;
  3.   for (Directory d : childrenDirectories)
  4.     macollec.addAll(d.getTxtFiles());


Bon, là c'est fessée direct, la récursivité n'est pas terminale (encore que sur un arbre on s'en fout), mais surtout, tu va allouer et merger des centaines de collections intermédiaires.
 
Comme la joe-la-pelle-à-clous rôde, et que y'en a marre du java qui rame à cause du développeur, tu fais un petit effort.
 

Code :
  1. public Collection<File> getTxtFiles() {
  2.   Collection<File> maCollec = new ArrayList<File>;
  3.   addTxtFilesTo(maCollec);
  4.   return maCollec;
  5. }
  6. public void addTxtFilesTo(Collection<File> c) {
  7.   for(File f : files)
  8.     if (f.isTxt())
  9.       c.add(f);
  10.   for(Directory d : childrenDirectories)
  11.     d.addTxtFilesTo(c);
  12. }


bon, ça c'est cool, c'est un bon pattern que tout le monde devrait connaître et exposer : la version pas prise de tête et la version où on pousse dedans (pareil pour toString() et writeOn(Writer w) que ces crétins de sun n'ont pas fait tout seuls). en général, on en écrit un à partir de l'autre.
 
 
voyant ceci, joe la termite ce dit : "c'est pas con, je collectionne tout un tas de bordel dont tous les fichiers textes de certains répertoires et certains autres répertoires ailleur dans l'arborescence, je vais utiliser addTxtFilesTo()".
 

Code :
  1. Collection<DirectoryEntry> c = new ArrayList<DirectoryEntry>();
  2. c.add(directory1);
  3. c.add(directory2);
  4. c.add(unFichierALaCon);
  5. directory12.addTxtFilesTo(c); //boum !!!


joe-la-termite, il vient de te niquer ta belle fonction réutilisable ! bah oui, Collection<File> c'est pas Collection<DirectoryEntry> et tu arrête de pleurer comme ça.
 
 
c'est là qu'arrive l'acharné de la spec java 5.0 et qui dit : "trop facile pour moi".
 
et la soluce arrive toute seule :

Code :
  1. void addTxtFileTo(Collection<? super File> c){
  2. ...
  3. }


 
et voiloù, il autorise à passer en argument n'importe quelle collection capable de contenir des File.


Message édité par nraynaud le 19-01-2005 à 21:17:20
Reply

Marsh Posté le 17-01-2005 à 21:25:55    

[:blueflag]

Reply

Marsh Posté le 18-01-2005 à 00:15:56    

[:rofl]
 


---------------
Jubi Photos : Flickr - 500px
Reply

Marsh Posté le 18-01-2005 à 09:18:16    

ouaip ok d'accord pas mal :D
pour le coup du extends, la nuit m'a porté conseil, et je comprends que ça marche ...


---------------
get amaroK plugin
Reply

Marsh Posté le 18-01-2005 à 09:21:58    

Mais dans mon cas, je vois pas l'utilité de la chose :/
Moi ça me suffit comme ça :

Code :
  1. public class TestA<B> { 
  2.     B b; 
  3.     TestD<TestC<B>> d; 
  4.      
  5.     public <T> T plop(TestE<T,B,TestC<B>> e) {


---------------
get amaroK plugin
Reply

Marsh Posté le 18-01-2005 à 12:02:03    

pour pouvoir passer en argument des PerceptionInterface2 admettant en paramètre des superclasses de Environment1

Reply

Marsh Posté le 18-01-2005 à 12:04:15    

nraynaud a écrit :

pour pouvoir passer en argument des PerceptionInterface2 admettant en paramètre des superclasses de Environment1


Ha d'accord ! mais conceptuellement c'est pas possible :D
Car le Environment1 de l'exemple est une top-classe chez moi :)


Message édité par bobuse le 18-01-2005 à 12:04:36

---------------
get amaroK plugin
Reply

Marsh Posté le 18-01-2005 à 13:01:52    

g compris l'interet de ce truc pour les collections par ex...mais après je dois avouer que ca sort de ma compétence


---------------
Jubi Photos : Flickr - 500px
Reply

Marsh Posté le 18-01-2005 à 13:26:20    

ben c'est utile pour faire des API génériques


---------------
get amaroK plugin
Reply

Marsh Posté le 18-01-2005 à 13:39:28    

non, justement, là c'est pour *utiliser* des apis génériques, ton bout de code à toi, il ne l'est pas du tout. [:aloy]

Reply

Marsh Posté le 18-01-2005 à 13:58:01    

Ben le fait que mes poissons soient paramétrés par un type de position, je voie pas quelle API j'utilise :??:
 
Bon et sinon, mon autre topic :D ? des idées ?


---------------
get amaroK plugin
Reply

Marsh Posté le 18-01-2005 à 14:04:39    

oui, mais il faut que je lise la spec qui est chez moi :o

Reply

Marsh Posté le 18-01-2005 à 15:57:28    

Jubijub a écrit :

g compris l'interet de ce truc pour les collections par ex...mais après je dois avouer que ca sort de ma compétence


héhé
c'est pour empecher la banalisation de l'info :D

Reply

Marsh Posté le 18-01-2005 à 16:01:40    

bon, [:blueflag], donc.

Reply

Marsh Posté le 18-01-2005 à 17:08:02    

nraynaud : tant que t'y es, rejette un coup d'oeil aux specs swing, et fais nous un tuto :ange:


---------------
Jubi Photos : Flickr - 500px
Reply

Marsh Posté le 18-01-2005 à 17:12:00    

question tuto, celui de sun est pas mal, mais dur à digérer je trouve :/
J'ai beau le relire, et comprendre ce qu'il veut dire, j'oublie souvent :D
Il y a celui de dev.com aussi :
http://lroux.developpez.com/articl [...] #Lgenerics


---------------
get amaroK plugin
Reply

Marsh Posté le 18-01-2005 à 17:23:46    

Jubi > y'a pas de specs en swing [:benou]

Reply

Marsh Posté le 18-01-2005 à 17:26:53    

bobuse > nan je projette de faire un tuto sur l'archi plutôt que sur les détails.

Reply

Marsh Posté le 19-01-2005 à 12:29:43    

J'ai regardé de près et...
 
bobuse >
 
Dans :

Code :
  1. public <T,C extends TestC<B>> T plop(TestE<T,B,C> e)


tu declares le type C comme "C extends TestC<B>". La fonction

Code :
  1. public T plop(B b,C c);


dans TestE veut un C du type "C extends TestC<B>" or toi lors de l'appel :

Code :
  1. return e.plop(b,d.getC());


tu l'appelles avec un "TestC<B>" ce qui n'est pas pareil.
La preuve par l'exemple : (en modifiant ta classe TestE)

Code :
  1. class TestE<T,B,C extends TestC<B>> {
  2.     public T plop(B b,C c) {
  3.  TestC<B> obj;
  4.  Collection<C> coll = new LinkedList<C>();
  5.  //ok
  6.  coll.add(c);
  7.  //crack a la compilation car on ne sait pas ce que contient coll!
  8.  //donc c ne doit pas etre exactement un "TestC<B>"
  9.  coll.add(obj);
  10.  return null;
  11. }
  12. }


 
 Les types en generiques
sont exacts.
 
 
nraynaud >
 
 
chez moi en mettant super a la place de extends j'ai 3 msg d'erreur [:joce] :
 

Code :
  1. Compiling 1 source file to /home/kroax/prog/java/mes_prog/Generic/build/classes
  2. /home/kroax/prog/java/mes_prog/Generic/src/generic/Gen.java:6: > expected
  3.     public <T,C super TestC<B>> T plop(TestE<T,B,C> e) {
  4. /home/kroax/prog/java/mes_prog/Generic/src/generic/Gen.java:11: illegal start of type
  5. }
  6. /home/kroax/prog/java/mes_prog/Generic/src/generic/Gen.java:10: <identifier> expected
  7.     }
  8. 3 errors
  9. BUILD FAILED (total time: 0 seconds)


 

Reply

Marsh Posté le 19-01-2005 à 12:56:59    

ça a été viré de la norme ????
 
je le retrouve plus.

Reply

Marsh Posté le 19-01-2005 à 14:30:14    

Giz> oui effectivement, ton explication est pas mal. Merci :)


---------------
get amaroK plugin
Reply

Marsh Posté le 19-01-2005 à 21:17:49    

j'ai changé la syntaxe du super, ça doit être mieux.

Reply

Marsh Posté le 20-01-2005 à 09:23:31    

nraynaud a écrit :

j'ai changé la syntaxe du super, ça doit être mieux.


 
heink ?
je vois pas ...


---------------
get amaroK plugin
Reply

Marsh Posté le 20-01-2005 à 13:44:11    

Code :
  1. void addTxtFileTo(Collection<? super File> c){
  2. ...
  3. }

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed