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