简体   繁体   English

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

[英]java - How to create an instance of generic type T

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. 但是在handleNewConnectionRequest(...)方法中,我无法创建T的实例,因为它实际上不是类。 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 . 此外,我不能使用此处提到的方法因为我想传递socket实例,以便请求处理程序可以在socket上获取OutputStreamInputStream


Can't I make a generic server like above and have different protocol handlers eg 我不能像上面那样制作通用服务器,并且有不同的协议处理程序,例如

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

You'll need an instance of the class. 你需要一个类的实例。 The generic type T isn't enough. 通用类型T是不够的。 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();
    }
}

Maybe make different Server subclasses befitting various handler types. 也许使不同的Server子类适合各种处理程序类型。 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... 只是一个想法...

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

    }
}

You can't do it directly like that with generics in Java. 你不能像Java中的泛型一样直接这样做。 You can use Reflection if you get the actual class object of RequestHandler with getClass() . 如果使用getClass()获取RequestHandler的实际类对象,则可以使用Reflection。 You could try saving the class of the item in constructor and then write helper method like this: 你可以尝试在构造函数中保存项的类,然后编写如下的helper方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM