2010-04-02 6 views
17

J'écris une application pour effectuer des calculs distribués dans un réseau pair-à-pair. En définissant le réseau, j'ai deux classes P2PNetwork et P2PClient. Je veux que ces génériques et ont donc les définitions de:Création de références génériques circulaires

P2PNetwork<T extends P2PClient<? extends P2PNetwork<T>>> 

P2PClient<T extends P2PNetwork<? extends T>> 

avec P2PClient définir une méthode de setnetwork (réseau T). Ce que je suis l'espoir de décrire avec ce code est:

  1. A P2PNetwork est constitué de clients d'un certain type
  2. Un P2PClient ne peut appartenir à un réseau dont les clients se composent du même type que cette client (la circulaire de référence )

Cela semble correct pour moi, mais si je tente de créer une version non générique tel que

MyP2PClient<MyP2PNetwork<? extends MyP2PClient>> myClient; 

et d'autres variantes Je reçois de nombreuses erreurs du compilateur. Donc, mes questions sont les suivantes:

  1. est une référence circulaire générique même possible (je ne l'ai jamais rien vu interdire explicitement)?
  2. La définition générique ci-dessus est-elle la définition correcte d'une telle relation circulaire ?
  3. Si elle est valide, est le « correct » façon de décrire une telle relation (à savoir est-il une autre valide définition, qui est stylistiquement préféré)?
  4. Comment définir correctement une instance non générique d'un client et Server donné la bonne définition générique ?
+0

Je n'ai toujours pas été en mesure de trouver une réponse définitive sur « est-il possible », mais de plus la lecture et les tentatives, je crois qu'il est possible de créer la définition, mais pas pour instancier les objets qui l'utilisent. –

Répondre

24

Des références génériques circulaires sont en effet possibles. Java Generics and Collections inclut plusieurs exemples.Pour votre cas, un tel spécimen ressemblerait à ceci:

public interface P2PNetwork<N extends P2PNetwork<N, C>, 
          C extends P2PClient<N, C>> { 
    void addClient(C client); 
} 

public interface P2PClient<N extends P2PNetwork<N, C>, 
          C extends P2PClient<N, C>> { 
    void setNetwork(N network); 
} 

class TorrentNetwork implements P2PNetwork<TorrentNetwork, TorrentClient> { 
    @Override 
    public void addClient(TorrentClient client) { 
    ... 
    } 
} 

class TorrentClient implements P2PClient<TorrentNetwork, TorrentClient> { 
    @Override 
    public void setNetwork(TorrentNetwork network) { 
    ... 
    } 
} 

... 

TorrentNetwork network = new TorrentNetwork(); 
TorrentClient client = new TorrentClient(); 

network.addClient(client); 
+2

Ok, donc votre réponse était il y a 6 ans, mais ça m'a quand même aidé à résoudre un gros mal de tête que j'avais essayé d'obtenir pour que le jeu <...> et GamePlayer <...> fonctionnent correctement! Certainement mon truc préféré à propos de Stack Exchange. – corsiKa

3

Il nous est peut-être utile de vous répondre si vous avez défini ce que signifie "un certain type", c'est-à-dire quelles sont les différences entre différents "types" de réseaux P2P.

Mais au lieu d'exprimer la relation de dépendance/circulaire en termes de l'autre, il pourrait être plus facile d'exprimer en introduisant une troisième classe, le P2PType:

public class P2PNetwork<T extends P2PType> { 
    ... 
} 
public class P2PClient<T extends P2PType> { 
    ... 
    public void setNetwork(P2PNetwork<T> network) { ... } 
} 

je pourrais être sur quelque chose, mais je pense que ce permettrait au compilateur de faire en sorte que P2Plients fasse partie de P2PNetworks du même type générique. Cette approche peut cependant s'effondrer si le "type" n'est pas quelque chose qui peut s'exprimer comme un objet lui-même, ie si le P2PType n'est pas quelque chose qui aurait des méthodes, un comportement polymorphique, etc.

+0

La pensée est le type est le but du réseau. Un exemple inventé: un réseau pour calculer les nombres de Fibbonnacci par rapport aux nombres premiers vs déterminer le sens de la vie. La prémisse est la base de la classe de réseau est responsable de maintenir l'état et la connectivité du réseau, le client de base pour la propagation des informations sur le réseau et la gestion de la tâche réelle du réseau. Cela dit, ceci est également devenu un intérêt académique pour savoir si des définitions génériques circulaires sont possibles et, dans l'affirmative, comment elles seraient réalisées. –