2011-10-28 13 views
9

Sto scrivendo un server come qui di seguitojava - Come creare un'istanza di tipo generico T

public class Server<T extends RequestHandler> { 

    public void start() { 

     try{ 
      this.serverSocket = new ServerSocket(this.port, this.backLog); 
     } catch (IOException e) { 
      LOGGER.error("Could not listen on port " + this.port, e); 
      System.exit(-1); 
     } 

     while (!stopTheServer) { 
      socket = null; 
      try { 
       socket = serverSocket.accept(); 
       handleNewConnectionRequest(socket); 
      } catch (IOException e) { 
       LOGGER.warn("Accept failed at: " + this.port, e); 
       e.printStackTrace(); 
      } 
     } 

    } 

    protected void handleNewConnectionRequest(Socket socket) { 
     try { 
      executorService.submit(new T(socket)); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Ma nel metodo handleNewConnectionRequest(...), non posso creare un'istanza di T in quanto non è in realtà una classe . Inoltre, non è possibile utilizzare il metodo menzionato here poiché voglio passare l'istanza socket in modo che il gestore richieste possa ottenere OutputStream e InputStream su socket.


non è possibile fare un server generico come sopra e hanno diversi gestori di protocollo ad esempio

public class HttpRequestHandler extends RequestHandler { 
    ... 
} 

public class FtpRequestHandler extends RequestHandler { 
    ... 
} 

public class SmtpRequestHandler extends RequestHandler { 
    ... 
} 

e poi li usano come qui di seguito

Server<HttpRequestHandler> httpServer = new Server<HttpRequestHandler>(); 
Server<FtpRequestHandler> ftpServer = new Server<FtpRequestHandler >(); 
Server<SmtpRequestHandler> smtpServer = new Server<SmtpRequestHandler >(); 

risposta

5

magari fare diverse sottoclassi Server addicono vari tipi di gestore. Un esempio:

public class HttpServer extends Server<HttpRequestHandler> { 

    protected HttpRequestHandler wrapSocket(Socket socket) { 
     return new HttpRequestHandler(socket); 
    } 

} 

e adattare Server in questo modo:

public abstract class Server<T extends RequestHandler> { 

    protected abstract T wrapSocket(Socket socket); 

    protected void handleNewConnectionRequest(Socket socket) { 
     try { 
      executorService.submit(wrapSocket(socket)); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

Solo un pensiero ...

+2

+1. Oppure fai in modo che il server usi una RequestHandlerFactory e chiedi a questa fabbrica di creare un RequestHandler ogni volta che il server ne ha bisogno. –

+0

@ JBNizet Ehi, ancora meglio! Ho trovato classi astratte/implementazioni e parametri di tipo per essere veramente buoni amici per il design OO. –

0

Non puoi farlo direttamente così con i generici in Java. È possibile utilizzare Reflection se si ottiene l'oggetto classe attuale di RequestHandler con getClass(). Si potrebbe provare a salvare la classe della voce nel costruttore e poi scrivere metodo di supporto in questo modo:

Save the class object (in constructor for example): 
this.clazz = requestHandler.getClass() 

Then create new object of same class: 
E instantiate(Class<E> clazz) 
{ 
    return clazz.newInstance(); 
} 
9

avrete bisogno di un'istanza della classe. Il tipo generico T non è sufficiente. Così farai:

class Server <T extends RequestHandler> { 
    Class<T> clazz; 
    public Server(Class<T> clazz) { 
     this.clazz = clazz; 
    } 

    private T newRequest() { 
     return clazz.newInstance(); 
    } 
} 
1

Non lo sai. Non ha senso. In questo caso probabilmente eviterei i farmaci generici. Semplice vecchia interfaccia o classe astratta fa un lavoro. È possibile creare server astratto con metodo factory astratto.

abstract class Server { 
    abstract protected RequestHandler newRequest(Socket socket); 
    ... same as before 
} 
+0

+1 Questo sembra avere più senso e si presta a una facile lettura. Non sono sicuro che ci sia molto da guadagnare dal modello Factory qui. I costrutti linguistici sono la strada da percorrere. –

0
/* =================|Cassandra to Java Connection|===================== */ 
package demo_cassandra_connection; 

import com.datastax.driver.core.Cluster; 
import com.datastax.driver.core.Row; 
import com.datastax.driver.core.Session; 

public class java_to_cassandra_connection 
{ 
    public static void main(String[] args) 
    { 
     com.datastax.driver.core.Session ses; 
     Cluster cluster= 
     Cluster.builder().addContactPoints("54.191.46.102", 
     "54.149.32.12", "54.191.43.254") 
     .withPort(9042).withCredentials("cassandra","cassandra").build(); 
     ses = cluster.connect(); 
     Session session = (Session) cluster.connect(); 
     String cqlStatement = "SELECT * FROM testapp.user"; 
     for (Row row : ((com.datastax.driver.core.Session) 
     session).execute(cqlStatement)) 
     { 
      System.out.println(row.toString()); 
     } 

    } 
} 
Problemi correlati