簡體   English   中英

方法的泛型重載-解決方法

[英]Generics overloading of method - workaround

這個問題被問過很多次,但是我找不到適合的解決方法。 該示例按需工作:

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

但是我需要在Service類中再添加一個方法,以在調用invoke方法之前/之后執行一些操作:

public void invoke(RequestWrapper<?> wrapper) {
    try {
        // ...
        invoke(wrapper.getType().cast(wrapper.getRequest()));
        invoke(wrapper.getRequest());
    } catch(Exception e ) {
        // ...
    }
}

那么main方法將包含:

new Service().invoke(sw);

我了解為什么使用invoke(Object request)而不是invoke(String request)的原因。 調用適當的invoke方法並能夠在此方法之前/之后執行一些常見操作的最佳解決方案是什么?

要具有接口(例如Invoker),請實現它,例如StringInvoker,Invoker>並調用map.get(wrapper.getType())。invoke(wrapper.getRequest())是可能的解決方案,但我希望有更好的選擇。

例如,您可以檢查類型並將其顯式轉換(我還添加了Integer以便可以看到更多類型的分支):

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)

注意:

如果走這條路,甚至不需要將請求類型存儲在RequestWrapper類中,因為您可以輕松地在請求本身上使用instanceof運算符來檢查其類型。 而且,如果您“擺脫”請求類型,則當前的RequestWrapper類將僅包含該請求,因此在這種情況下甚至不需要RequestWrapper

訪客模式可以用來解決它。 唯一的缺點是無法編寫:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM