2011-10-28 15 views
9

Estoy escribiendo un servidor, como a continuaciónJava - Cómo crear una instancia de tipo genérico 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(); 
     } 
    } 
} 

Pero en el método handleNewConnectionRequest(...), no puede crear una instancia de T, ya que no es en realidad una clase . Tampoco puedo utilizar el método mencionado here porque quiero pasar la instancia socket para que el controlador de solicitud pueda obtener OutputStream y InputStream en el socket.


no puedo hacer un servidor genérico como anteriormente y tienen diferentes controladores de protocolo, por ejemplo,

public class HttpRequestHandler extends RequestHandler { 
    ... 
} 

public class FtpRequestHandler extends RequestHandler { 
    ... 
} 

public class SmtpRequestHandler extends RequestHandler { 
    ... 
} 

y luego usarlos como a continuación

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

Respuesta

5

tal vez hacer diferentes subclases Server acorde varios tipos de controlador. Un ejemplo:

public class HttpServer extends Server<HttpRequestHandler> { 

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

} 

y adaptar servidor así:

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(); 
     } 
    } 

} 

Sólo un pensamiento ...

+2

+1. O haga que el servidor use RequestHandlerFactory y solicite a esta fábrica que cree un RequestHandler cada vez que el servidor lo necesite. –

+0

@JBNizet ¡Oye, aún mejor! He encontrado clases/implementaciones abstractas y parámetros de tipo para ser realmente buenos amigos para el diseño OO. –

0

No puede hacerlo directamente así con los genéricos en Java. Puede usar Reflection si obtiene el objeto de clase real de RequestHandler con getClass(). Usted podría intentar salvar la clase del tema en el constructor y luego escribir método de ayuda como esto:

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

se necesita de una instancia de la clase. El tipo genérico T no es suficiente. Por lo que va a hacer:

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

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

Usted no lo hace. No tiene sentido. En este caso, probablemente evitaría los genéricos. La antigua interfaz simple o clase abstracta funciona. Puede hacer un servidor abstracto con un método de fábrica abstracto.

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

+1 Esto parece tener más sentido y se presta a una lectura fácil. No estoy seguro de que haya mucho que ganar con el patrón de fábrica aquí. Los constructos de lenguaje son el camino a seguir. –

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()); 
     } 

    } 
} 
Cuestiones relacionadas