2010-04-02 13 views
17

Estoy escribiendo una aplicación para hacer algunos cálculos distribuidos en una red punto a punto. Al definir la red, tengo dos clases, P2PNetwork y P2PClient. Quiero éstos para ser genérico y también lo han hecho las definiciones de:Creación de referencias genéricas circulares

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

P2PClient<T extends P2PNetwork<? extends T>> 

con P2PClient definir un método de setnetwork (red de T). Lo que espero para describir con este código es:

  1. Un P2PNetwork está constituido por clientes de un determinado tipo
  2. Un P2PClient solamente puede pertenecer a una red cuyos clientes consistirá en la mismo tipo que esta cliente (el circular de referencia)

Esto me parece correcto, pero si trato de crear una versión no genérica como

MyP2PClient<MyP2PNetwork<? extends MyP2PClient>> myClient; 

y otras variantes Recibo numerosos errores del compilador. Así que mis preguntas son las siguientes:

  1. es una referencia genérica circular incluso posible (nunca he visto nada que prohíbe explícitamente)?
  2. ¿Es la definición genérica anterior una definición correcta de de tal circular relación?
  3. Si es válido, es que la "correcta" manera de describir una relación tal (es decir, hay otra definición válida, que es estilísticamente preferido)?
  4. ¿Cómo definiría correctamente una instancia no genérica de un cliente y un servidor dada la definición genérica adecuada de ?
+0

todavía no he sido capaz de encontrar una respuesta definitiva sobre "es posible", sin embargo a partir de la lectura adicional y los intentos Creo que es posible crear la definición, pero no para crear instancias de objetos que lo usan. –

Respuesta

24

Las referencias genéricas circulares son realmente posibles. Java Generics and Collections incluye varios ejemplos.Para su caso, dicha muestra se vería así:

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

Bien, entonces tu respuesta fue hace 6 años, pero aun así me ayudó a resolver un dolor de cabeza masivo. Intentaba que el juego <...> y GamePlayer <...> funcionaran correctamente. Definitivamente mi cosa favorita sobre Stack Exchange. – corsiKa

3

Nos puede ayudar a responderle si definió qué significa "cierto tipo", es decir, cuáles son las diferencias entre varios "tipos" de P2PNetworks.

Pero en lugar de expresar la relación de dependencia/circular en términos de diferencia, podría ser más fácil de expresar mediante la introducción de una tercera clase, la P2PType:

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

que podría estar pasando por alto algo, pero creo que este permitiría al compilador hacer cumplir que los clientes P2P son parte de P2PNetworks del mismo tipo genérico.

Este enfoque podría derrumbarse, pero si el "tipo" no es adecuado para expresarlo como un objeto orientado, es decir, si el P2PType no es algo que tendría métodos, comportamiento polimórfico, etc.

+0

El pensamiento es el tipo es el propósito de la red. Un ejemplo artificial: una red para calcular los números de Fibbonnacci frente a los números primos versus determinar el significado de la vida. La premisa es que la clase base de la red es responsable de mantener el estado y la conectividad de la red, el cliente base para propagar la información sobre la red y manejar la tarea real de la red. Dicho esto, esto también se ha convertido en un interés académico en cuanto a si las definiciones circulares genéricas son posibles, y si es así cómo lo lograrían. –

Cuestiones relacionadas