Общая перегрузка метода - обходной путь

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

Но мне нужно добавить еще один метод в класс Service, который делает что-то до/после вызова метода invoke:

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

то основной метод будет содержать:

new Service().invoke(sw);

Я понимаю причину, почему invoke (Object request) используется вместо invoke (запрос String). Что было бы элегантным решением для вызова надлежащего метода вызова и выполнения некоторых общих действий до/после него?

Чтобы иметь интерфейс, например Invoker, реализуйте его, например StringInvoker, Invoker> и вызывайте map.get(wrapper.getType()). Invoke (wrapper.getRequest()) - это возможное решение, но я ожидаю чего-то лучшего.

Теги:
generics

2 ответа

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

Вы можете проверить тип и явно бросить его, например (я также добавил 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 даже не понадобится в этом случае.

  • 0
    Да, но это именно то, от чего я хотел избавиться. Другая идея, как воспользоваться перегрузкой метода?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню