2014-10-02 4 views
1

이 질문은 여러 번 묻는 질문 있지만 우아한 해결 방법을 찾을 수 없습니다.메서드의 제네릭 오버로드 - 해결 방법

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 메소드의 호출 후 전에 뭔가를 할 클래스/서비스하는 또 하나의 방법을 추가해야합니다 : 이 예는 원하는대로 작동

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

다음의 주요 방법이 포함됩니다 :

new Service().invoke(sw); 

invoke (String request) 대신 invoke (Object request)가 사용 된 이유를 알고 있습니다. 적절한 호출 메소드를 호출하고 그 전후에 몇 가지 공통적 인 조치를 취할 수있는 우아한 해결책은 무엇입니까?

예 : 호출자, 구현자, 예 : StringInvoker, Invoker> 그리고 call map.get (wrapper.getType()). invoke (wrapper.getRequest())는 가능한 해결책이지만, 나는 더 나은 것을 기대한다.

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) 

참고 :

당신이가는 경우

당신은 캐스팅을 명시 적으로 유형을 확인 할 수 있습니다

답변

0

방문객 후편은이를 해결할 수 있습니다.

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

예를 들어 (I는 또한 당신이 더 많은 유형에 분기 볼 수 있습니다 Integer 추가) 이 경로에서는 RequestWrapper 클래스에 요청 유형을 저장할 필요가 없기 때문에 요청 자체에서 instanceof 연산자를 사용하여 유형을 쉽게 확인할 수 있습니다. 요청 유형을 "없애"면 현재 RequestWrapper 클래스에는 요청 만 포함되어 있으므로이 경우에는 RequestWrapper이 필요하지 않습니다.

+0

그래,하지만 내가 없애 싶어 정확히입니다. 메소드 오버로딩의 이점을 취하는 다른 아이디어? – Samot

관련 문제