2011-10-28 29 views
9

Tôi viết một máy chủ như dưới đâyjava - Làm thế nào để tạo ra một thể hiện của loại generic 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(); 
     } 
    } 
} 

Nhưng trong phương pháp handleNewConnectionRequest(...), tôi không thể tạo ra một thể hiện của T vì nó là thực sự không phải là một lớp . Ngoài ra tôi không thể sử dụng phương pháp được đề cập here vì tôi muốn chuyển thể hiện socket để trình xử lý yêu cầu có thể nhận được OutputStreamInputStream trên số socket.


Tôi không thể làm cho một máy chủ chung chung như trên và có xử lý giao thức khác nhau ví dụ như

public class HttpRequestHandler extends RequestHandler { 
    ... 
} 

public class FtpRequestHandler extends RequestHandler { 
    ... 
} 

public class SmtpRequestHandler extends RequestHandler { 
    ... 
} 

và sau đó sử dụng chúng như dưới đây

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

Trả lời

5

Có thể làm cho các loại trình xử lý khác nhau khác nhau. Một ví dụ:

public class HttpServer extends Server<HttpRequestHandler> { 

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

} 

Và thích ứng máy chủ như vậy:

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

} 

Chỉ cần một ý nghĩ ...

+2

+1. Hoặc làm cho máy chủ sử dụng RequestHandlerFactory và yêu cầu nhà máy này tạo một RequestHandler mỗi khi máy chủ cần. –

+0

@JBNizet Hey, thậm chí tốt hơn! Tôi đã tìm thấy các lớp/triển khai trừu tượng và các tham số kiểu để trở thành những người bạn thực sự tốt cho thiết kế OO. –

0

Bạn không thể làm điều đó trực tiếp như thế với Generics trong Java. Bạn có thể sử dụng Reflection nếu bạn nhận được đối tượng lớp thực tế của RequestHandler với getClass(). Bạn có thể thử lưu lớp của mục trong hàm tạo và sau đó viết phương thức trợ giúp như sau:

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

Bạn sẽ cần một thể hiện của lớp. Loại T chung không đủ. Vì vậy, bạn sẽ làm:

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

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

Bạn không có. Nó không có ý nghĩa. Trong trường hợp này, tôi có lẽ nên tránh generics. Giao diện cũ hoặc lớp trừu tượng cũ làm công việc. Bạn có thể làm cho máy chủ trừu tượng với phương pháp nhà máy trừu tượng.

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

+1 Điều này có vẻ có ý nghĩa nhất và dễ dàng tự đọc. Tôi không chắc chắn có nhiều để đạt được từ các mô hình nhà máy ở đây. Các cấu trúc ngôn ngữ là cách để đi. –

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

    } 
} 
Các vấn đề liên quan