2011-10-28 22 views
9
實例

我寫類似下面爪哇 - 如何,因爲它實際上不是一個類來創建泛型類型的牛逼

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

但在handleNewConnectionRequest(...)方法,我不能創建T的實例的服務器。此外,我不能使用方法here,因爲我想通過socket實例,以便請求處理程序可以在socket上獲得OutputStreamInputStream


我不能做一個普通的服務器上面的一樣,有不同的協議處理程序,例如

public class HttpRequestHandler extends RequestHandler { 
    ... 
} 

public class FtpRequestHandler extends RequestHandler { 
    ... 
} 

public class SmtpRequestHandler extends RequestHandler { 
    ... 
} 

,然後用它們像下面

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

回答

5

可能做出不同的Server子類相稱的各種處理程序類型。舉個例子:

public class HttpServer extends Server<HttpRequestHandler> { 

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

} 

和適應服務器,像這樣:

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

} 

只是一個想法...

+2

+1。或者讓服務器使用RequestHandlerFactory ,並要求該工廠在每次服務器需要時創建一個RequestHandler 。 –

+0

@JBNizet嘿,更好!我發現抽象類/實現和類型參數是面向對象設計的真正好朋友。 –

0

你不能直接做就像Java中的泛型一樣。如果使用getClass()獲取RequestHandler的實際類對象,則可以使用Reflection。您可以嘗試在構造函數中保存該項目的類,然後編寫如下幫助程序方法:

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

您需要一個類的實例。通用類型T是不夠的。所以,你會做:

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

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

你不知道。這沒有意義。在這種情況下,我可能會避免泛型。簡單的舊界面或抽象類做工作。您可以使用抽象工廠方法制作抽象服務器。

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

+1這似乎是最有意義的,並使本身易於閱讀。我不確定這裏的工廠模式有多大收穫。語言結構是要走的路。 –

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

    } 
}