java - 如何创建泛型类型 T 的实例

发布于 2024-12-12 05:42:27 字数 1824 浏览 0 评论 0原文

我正在编写一个如下所示的服务器,

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 的实例,因为它实际上不是一个类。另外,我无法使用此处提到的方法,因为我想传递 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 >();

I am writing a server like below

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

But in the handleNewConnectionRequest(...) method, I can't create an instance of T as it is actually not a class. Also I can't use the method mentioned here as I want to pass the socket instance so that the request handler can get OutputStream and InputStream on the socket.


Can't I make a generic server like above and have different protocol handlers e.g

public class HttpRequestHandler extends RequestHandler {
    ...
}

public class FtpRequestHandler extends RequestHandler {
    ...
}

public class SmtpRequestHandler extends RequestHandler {
    ...
}

and then use them like below

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

后知后觉 2024-12-19 05:42:27

您将需要该类的一个实例。泛型类型 T 还不够。所以你会这样做:

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

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

You'll need an instance of the class. The generic type T isn't enough. So you'll do:

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

    private T newRequest() {
        return clazz.newInstance();
    }
}
北城挽邺 2024-12-19 05:42:27

也许制作不同的 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();
        }
    }

}

只是一个想法......

Maybe make different Server subclasses befitting various handler types. One example:

public class HttpServer extends Server<HttpRequestHandler> {

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

}

And adapt Server like so:

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

}

Just a thought...

灼疼热情 2024-12-19 05:42:27

你不知道。这没有道理。在这种情况下,我可能会避免使用泛型。普通的旧接口或抽象类可以完成工作。您可以使用抽象工厂方法来创建抽象服务器。

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

You don't. It doesn't make sense. In this case I'd probably avoid generics. Plain old interface or abstract class does job. You can make abstract server with abstract factory method.

abstract class Server {
    abstract protected RequestHandler newRequest(Socket socket);
    ... same as before
}
眼角的笑意。 2024-12-19 05:42:27

你不能像 Java 中的泛型那样直接做到这一点。如果您使用 getClass() 获取 RequestHandler 的实际类对象,则可以使用反射。您可以尝试在构造函数中保存该项目的类,然后编写如下辅助方法:

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

You can't do it directly like that with generics in Java. You can use Reflection if you get the actual class object of RequestHandler with getClass(). You could try saving the class of the item in constructor and then write helper method like this:

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();
}
面犯桃花 2024-12-19 05:42:27
/* =================|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());
        }

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

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文