Java 泛型重载方法-变通方法

Java 泛型重载方法-变通方法,java,generics,Java,Generics,这个问题被问了很多次,但我找不到合适的解决办法。 此示例按需要工作: public class RequestWrapper<T> { private final T request; private final Class<T> type; public RequestWrapper(T request, Class<T> type) { this.request = request; this.ty

这个问题被问了很多次,但我找不到合适的解决办法。 此示例按需要工作:

public class RequestWrapper<T> {
    private final T request;
    private final Class<T> type;

    public RequestWrapper(T request, Class<T> type) {
        this.request = request;
        this.type = type;
    }

    public T getRequest() {
        return request;
    }

    public Class<T> getType() {
        return type;
    }
}

public class Service {

    private void invoke(String request) {
        System.out.println("String:" + request);
    }   

    private void invoke(Object request) {
        System.out.println("Object:" + request + "," + request.getClass().getSimpleName());
    }   

    public static void main(String[] args) {
        RequestWrapper<String> sw = new RequestWrapper<String>("A", String.class);
        RequestWrapper<Integer> iw = new RequestWrapper<Integer>(Integer.valueOf(0), Integer.class);

        new Service().invoke(sw.getRequest());
        new Service().invoke(iw.getRequest());
    }
}
我理解使用invoke(对象请求)而不是invoke(字符串请求)的原因。 调用适当的invoke方法并能够在调用方法之前/之后执行一些常见操作,这是一个优雅的解决方案吗


要拥有一个接口,例如Invoker,请实现它,例如StringInvoker、Invoker>和call map.get(wrapper.getType()).invoke(wrapper.getRequest())是可能的解决方案,但我希望有更好的解决方案。

您可以检查类型并显式强制转换它,例如(我还添加了
Integer
,以便您可以看到更多类型的分支):

Class c=wrapper.getType();
if(c==String.class)
调用((字符串)wrapper.getRequest());//调用调用(字符串)
else if(c==Integer.class)
invoke((整数)wrapper.getRequest());//调用调用(整数)
其他的
调用(wrapper.getRequest());//调用调用(对象)
注意:


如果您走这条路,您甚至不需要将请求类型存储在
RequestWrapper
类中,因为您可以同样轻松地对请求本身使用
instanceof
操作符来检查其类型。如果您“摆脱”了请求类型,您当前的
RequestWrapper
类将只包含请求,因此在这种情况下甚至不需要
RequestWrapper

访问者模式可以解决此问题。唯一的缺点是无法写入:

new Service().invoke(new RequestWrapper<String>("A"));
newservice().invoke(newrequestwrapper(“A”);
我的实施:

public class Service {
    public void invoke(RequestWrapper<?> wrapper) {
        try {
            // ...
            wrapper.invoke(this);
        } catch(Exception e ) {
            // ...
        }
    }

    public void invoke(String request) {
        System.out.println("String:" + request);
    }   

    public void invoke(Boolean request) {
        System.out.println("Boolean:" + request);
    }       

    public static void main(String[] args) {
        RequestWrapper<Boolean> rw = new BooleanRequestWrapper(Boolean.TRUE);

        new Service().invoke(rw);
    }
}

abstract class RequestWrapper<T> {
    protected final T request;

    public RequestWrapper(T request) {
        this.request = request;
    }

    public abstract void invoke(Service v);
}

class BooleanRequestWrapper extends RequestWrapper<Boolean> {

    public BooleanRequestWrapper(Boolean request) {
        super(request);
    }

    public void invoke(Service service) {
        service.invoke(request);
    }
}
公共类服务{
公共void调用(RequestWrapper){
试一试{
// ...
调用(this);
}捕获(例外e){
// ...
}
}
公共void调用(字符串请求){
System.out.println(“字符串:+请求);
}   
公共void调用(布尔请求){
System.out.println(“布尔:+请求);
}       
公共静态void main(字符串[]args){
RequestWrapper rw=new BooleanRequestWrapper(Boolean.TRUE);
新服务().invoke(rw);
}
}
抽象类请求包装器{
受保护的最终T请求;
公共请求包装器(T请求){
this.request=请求;
}
公共抽象无效调用(服务v);
}
类BooleanRequestWrapper扩展了RequestWrapper{
公共布尔请求包装器(布尔请求){
超级(请求);
}
公共void调用(服务){
服务调用(请求);
}
}

是的,但这正是我想要摆脱的。如何利用方法重载的好处有不同的想法吗?
Class<?> c = wrapper.getType();

if (c == String.class)
    invoke((String) wrapper.getRequest());  // Invokes invoke(String)
else if (c == Integer.class)
    invoke((Integer) wrapper.getRequest()); // Invokes invoke(Integer)
else
    invoke(wrapper.getRequest());           // Invokes invoke(Object)
new Service().invoke(new RequestWrapper<String>("A"));
public class Service {
    public void invoke(RequestWrapper<?> wrapper) {
        try {
            // ...
            wrapper.invoke(this);
        } catch(Exception e ) {
            // ...
        }
    }

    public void invoke(String request) {
        System.out.println("String:" + request);
    }   

    public void invoke(Boolean request) {
        System.out.println("Boolean:" + request);
    }       

    public static void main(String[] args) {
        RequestWrapper<Boolean> rw = new BooleanRequestWrapper(Boolean.TRUE);

        new Service().invoke(rw);
    }
}

abstract class RequestWrapper<T> {
    protected final T request;

    public RequestWrapper(T request) {
        this.request = request;
    }

    public abstract void invoke(Service v);
}

class BooleanRequestWrapper extends RequestWrapper<Boolean> {

    public BooleanRequestWrapper(Boolean request) {
        super(request);
    }

    public void invoke(Service service) {
        service.invoke(request);
    }
}