[英]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.