Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2737 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  encore les generics

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

encore les generics

n°1236353
TheRom_S
Posté le 02-11-2005 à 13:56:40  profilanswer
 

Salut à tous,
 
j'ai découvert récemment les generics et leur puissance, mais j'en arrive à quelques problèmes.
En fait, j'ai des flux provenant d'un Socket à mapper sur différents types suivant mon cas d'utilisation :
un coup BufferedReader et String, un autre coup org.xml.sax.InputSource et org.jdom.Document, et après d'autres types encore ...
j'utilise un objet qui, pour gérer mes flux d'entrée, utilise lui-même d'autre objets paramétrables :

Code :
  1. // T1 par exemple BufferefReader
  2. // T2 par exemple String
  3. // T3 et T4, même style d'adaptation, mais en sortie
  4. public class MyController<T1, T2, T3, T4,
  5.         T5 extends MyReader<T1, T2, ?>,
  6.         T6 extends MyWriter<T3, T4, ?>> {
  7.     // declaration révélante pour l'exemple
  8.     T5 myReader;
  9.     // opération appellée par un MyReader
  10.     public boolean isReadable() { ... }
  11.     // opération utilisant un MyReader
  12.     public T2 read() { return this.myReader.read(); }
  13. }
  14. public class MyReader<T1, T2, C extends MonControlleur<T1, T2, ?, ?,
  15.         ? extends MyReader<T1, T2, C>,
  16.         ? extends MyWriter<?, ?, C>>> {
  17.     // declaration révélante pour l'exemple
  18.     C myController;
  19.     public T2 read() {
  20.         if (this.myController.isReadable()) { return ... ; }
  21.         else { return null; } // par exemple
  22.     }
  23. }
  24. public class MyWriter<T3, T4, C extends MonControlleur<?, ?, T3, T4,
  25.         ? extends MyReader<?, ?, C>,
  26.         ? extends MyWriter<T3, T4, C>>> { ... }
  27. // même chose


Ainsi, je peux vérifier 2 choses :
- grâce à la signature de MyController, je vérifie que le paramétrage de MyReader et MyWriter est bien dépendant des types T1 à T4
- grâce aux signatures de MyReader et MyWriter, que le MyController C passé est bien adapté aux types T1 à T4
 
Mes sources compilent sans aucun problème et sous NetBeans 5.0 beta, l'IDE ne me montrait aucune erreur.
Mais depuis que mon 5.0 beta est cassé (vivement la RC) je passe par Eclipse 3.1.1 qui me dit ceci pour MyReader (remplacer pour MyWriter) :

Citation :


Bound mismatch: The type ? extends MyReader<T1, T2, C> is not a valid substitute for the bounded parameter <T5 extends MyReader<T1, T2, ?>> of the type MyController<T1, T2, T3, T4, T5, T6>


 
Alors mes questions sont les suivantes :
- est-ce juste Eclipse qui gère pas ? après tout ça compile sans aucun [unchecked], rien, aucun warning (pour l'instant)
- est-ce que je vais trop loin dans la signature ?
exemple :

Code :
  1. public class ClassA<B extends ClassB<? extends ClassA<B extends ClassB<? extends ClassA<B extends ClassB<? extends ClassA<B extends ClassB<? extends ClassA<... // arf ou est-ce que je m'arrete ???


- même question à l'envers : ai-je vraiment besoin de spécifier un type T5 et T6 dans MyController et un type C dans les 2 autres ?
 
Donc j'espère ne pas trop vous torturer l'esprit avec mes questions et vous remercie d'avance pour vos réponses
 
ps: à quand le topic "passage obligé pour les débutants avec les generics" ?


---------------
The Rom's, à votre service
mood
Publicité
Posté le 02-11-2005 à 13:56:40  profilanswer
 

n°1236761
TheRom_S
Posté le 02-11-2005 à 18:56:28  profilanswer
 

petit up du soir ;p
vous comprenez mes questions ou je suis pas assez clair ? sinon dites-le
 
finalement la seule question valable est peut-etre
"a-t-on le droit d'utiliser les generics sur des classes abstraites pour obliger les classes dérivées (sans generic) à se conformer à ces règles, donc utiliser les generics uniquement dans le but de limiter les héritages grâce à des règles qui font que tout le système reste cohérent ?"
 
(et du coup ça a l'air beaucoup moins clair là :lol: )
 
voila, merci à ceux qui auront le courage de se creuser la tete pour m'aider dans mes aventures avec Java


---------------
The Rom's, à votre service
n°1237068
TheRom_S
Posté le 03-11-2005 à 00:32:23  profilanswer
 

bon, et bien apparemment, tout le monde sèche sur cette question, même les bons du forum.
Ce serait presque la gloire de voir que personne ne trouve mais en même temps ça m'arrange pas  :(
la prochaine fois, je demanderai pourquoi ma classe s'execute pas quand je clique dessus ou si je dois la renommer en .exe  :lol:
 
sinon, deux éléments de réponse :
- en remplaçant "? extends MyReader<T1, T2, C>" par "MyReader<T1, T2, C>",
il n'y a plus ce problème mais j'ai peur d'être bloqué par la suite en utilisant des classes dérivées :
(en gardant uniquement la partie concernant la foncion read)
public class StringController extends MyController<BufferedReader,String, ... , ... ,StringReader, ... > { ... }
public class StringReader extends MyReader<BufferedReader,String,StringController> { ... }
car StringReader est différent de MyReader<BufferedReader,String,StringController> (par ailleurs MyReader est abstraite)
 
- en remplaçant par "? super MyReader<T1, T2, C>" comme proposé par nraynaud dans un autre topic consacré aux generics,
le problème disparait aussi sauf que je peux alors utiliser un MyWriter puisque les deux fonctions dérivent d'une classe principale (qui se dérive pour gérer les ouvertures et fermetures de socket, la récupération des flux du socket pour les adapter en flux plus sympa et finalement l'écriture et la lecture de ces flux)
et là c'est plus bon puisque mes generics ne controllent plus la bonne utilisation.
 
bref je suis bloqué et je sais plus quoi faire
 
sinon, par rapport à netbeans, il ne marque pas d'erreur mais j'ai la ferme impression que c'est quand même ça qui le fait planter :)
(il recherche récursivement dans MyController puis MyReader dès qu'il essaie de proposer les champs ou méthodes après avoir appuyé sur . non ?)


---------------
The Rom's, à votre service
n°1237356
bobuse
Posté le 03-11-2005 à 12:16:20  profilanswer
 

Je capte pas tout mais j'ai l'impression que tu paramètres un peu inutilement ...
 
Dans MyController, tu te sers où de tes Tx ?
Au passage, danne desinitiales plus explicites, ça aide à la compréhension, genre : R extends MyReader, W extends MyWriter ...
 
D'autre part, je vois pas trop l'intérête de paramétrer un classe avec un joker !!!

Citation :

MyReader<T1, T2, C extends MonControlleur<T1, T2, ?, ?,  
        ? extends MyReader<T1, T2, C>, ? extends MyWriter<?, ?, C>>>


Ils te servent à quoi tes deux derniers ?
À moins que ce soit pour faire de l'introspection ...


---------------
get amaroK plugin
n°1237456
TheRom_S
Posté le 03-11-2005 à 13:54:43  profilanswer
 

oui en fait, y'avait un peu trop de paramétrage.
 
j'ai viré T5 et T6 (par rapport à l'exemple) comme paramètre de MyController
et dedans, j'utilise des variables
MyReader<T1,T2,? extends MyController<T1,T2,?,?>> myReader;
 
au lieu de
T5 myReader;
 
ça marche beaucoup mieux (netbeans remarche) car je peux quand même utiliser des classes dérivées (qui n'ont pas de méthodes en plus, juste l'implémentation de certaines méthodes abstraites)
 
ca me permet en plus de vérifier que le controller est adapté au reader (y'a les memes T1 et T2)
et le reader reste adapté au controller puisque sa signature est dans le controller
 
les 2 derniers ?, c'est parce que MyReader est indépendant de MyWriter qui les utilise :
MyWriter<T3,T4,? extends MyController<?,?,T3,T4>> myWriter;
 
et effectivement, je fais pas d'introspection (au sens java.lang.reflect)
 
donc la leçon de ce topic ? pas faire trop de paramétrage et éviter un paramétrage "récursif" ?


---------------
The Rom's, à votre service
n°1237513
bobuse
Posté le 03-11-2005 à 14:23:25  profilanswer
 

pourrais-tu repondre ton source, car je capte plus où tu en es ...


---------------
get amaroK plugin
n°1237879
TheRom_S
Posté le 03-11-2005 à 17:23:25  profilanswer
 

pas de pb si tu demandes,
faut voir que c'était jute un exemple, (je te file pas le projet complet parce qu'il est déja trop long)
Les classes de base

Code :
  1. import java.util.LinkedList;
  2. public class MyController<T1,T2,T3,T4> {
  3. T1 in;
  4. LinkedList<T2> inList;
  5. T3 out;
  6. LinkedList<T4> outList;
  7. MyReader<T1,T2,? extends MyController<T1,T2,?,?>> myReader;
  8. MyWriter<T3,T4,? extends MyController<?,?,T3,T4>> myWriter;
  9. public boolean isReadable() { return (this.in!=null); }
  10. public boolean isWritable() { return (this.out!=null); }
  11. public T1 getIn() { return this.in; }
  12. public T3 getOut() { return this.out; }
  13. public void setReader(MyReader<T1,T2,? extends MyController<T1,T2,?,?>> reader) {
  14.  this.myReader=reader;
  15. }
  16. public void setWriter(MyWriter<T3,T4,? extends MyController<?,?,T3,T4>> writer) {
  17.  this.myWriter=writer;
  18. }
  19. public T2 read() {
  20.  T2 tmp;
  21.  tmp=this.myReader.read();
  22.  inList.addLast(tmp);
  23.  return tmp;
  24. }
  25. public void write(T4 mess) { this.myWriter.write(mess); }
  26. }


Code :
  1. public abstract class MyReader<T1,T2,C extends MyController<T1,T2,?,?>> {
  2. T1 in;
  3. C myController;
  4. public MyReader(C controller) {
  5.  this.myController=controller;
  6.  this.in=this.myController.getIn();
  7.  this.myController.setReader(this);
  8. }
  9. public abstract T2 read();
  10. }


Code :
  1. public abstract class MyWriter<T3,T4,C extends MyController<?,?,T3,T4>> {
  2. T3 out;
  3. C myController;
  4. public MyWriter(C controller) {
  5.  this.myController=controller;
  6.  this.out=this.myController.getOut();
  7.  this.myController.setWriter(this);
  8. }
  9. public abstract void write(T4 mess);
  10. }


Et les implémentations

Code :
  1. import java.io.BufferedReader;
  2. import java.io.PrintWriter;
  3. public class StringController extends MyController<BufferedReader,String,PrintWriter,String> {
  4. public StringController() {
  5.  StringReader tmpr=new StringReader(this);
  6.  StringWriter tmpw=new StringWriter(this);
  7. }
  8. }


Code :
  1. import java.io.BufferedReader;
  2. public class StringReader extends MyReader<BufferedReader,String,StringController> {
  3. public StringReader(StringController controller) {
  4.  super(controller);
  5. }
  6. public String read() {
  7.  return new String("" );
  8.  // oui ben c'est un exemple test pour voir si ça compile et si ça fait planter l'IDE ou pas ;)
  9.  // sinon un truc genre : return this.in.readLine(); avec les try-catch qui vont bien
  10. }
  11. }


Code :
  1. import java.io.PrintWriter;
  2. public class StringWriter extends MyWriter<PrintWriter,String,StringController> {
  3. public StringWriter(StringController controller) {
  4.  super(controller);
  5. }
  6. public void write(String mess) {
  7.  // pareil, exemple sinon un truc genre : this.out.println(mess);
  8. }
  9. }


bon il manque plein de choses par rapport au vrai projet mais je pense que ça reflète bien la méthode que j'utilise
et du coup il n'y a pas besoin de paramétrer sur T5 et T6 comme avant ...
merci pour l'astuce / le recadrage en tout cas :hello:


---------------
The Rom's, à votre service

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  encore les generics

 

Sujets relatifs
[generics] un patron strategy paramétrable[Java] Serializer un Generics
[Tiger] generics : faire un "bridge"generics : round two
generics : unchecked conversiongenerics : besoin d'aspirine :D [Résolu]
Plus de sujets relatifs à : encore les generics


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR