Вопрос по inheritance, generics, java – Как вы можете передать List <объекты, которые реализуют интерфейс> в метод?

17

У меня есть сервлет, который передал параметры запроса, получает список объектов из DAO, превращает список в JSON и отправляет его обратно в ответ. Каждый список состоит из объектов, которые имеют метод:

public String getAsJson(){...}

И сервлет имеет множество в основном идентичных методов, которые выглядят так:

private String getUserListAsJson() {
    List<User> userList = this.dao.getUsers();
    StringBuilder builder = new StringBuilder();
    builder.append('[');
    // loops over the list appending the value of each objects getAsJson()
    builder.append(']');
    return builder.toString();
}

Проблема в том, что у меня есть около 6 методов (и их рост), которые выглядят именно так, за исключением разных запросов DAO. Моя идея состояла в том, чтобы создать интерфейс, который имел бы только определение для метода getAsJson (), сделать так, чтобы каждый компонент реализовал это, а затем иметь другой метод в сервлете, который брал объекты, которые реализовали этот интерфейс. В итоге выглядит так:

public Interface JsonEnabled {
    public String getAsJson();
}

public class User implements JsonEnabled {
    ....
    @Override
    public String getAsJson() {...}
}

public class TheServlet {
    ...
    private String getUserListAsJson() {
        List<User> userList = this.dao.getUsers();
        return this.getListAsJson(userList);
    }
    private String getListAsJson(List<? implements JsonEnabled> list) {
        // The loop code that is in each method.
    }
}

Таким образом, если кто-то действительно прочитал это далеко = P, это не компилируется, и после просмотра некоторой документации из Oracle, вы можете иметь толькоextends и неimplements для общих параметров. Создание всех классов происходит от абстрактного класса, в котором есть только метод getAsJson (), который не имеет смысла семантически (классы не связаны).

Я не нашел хорошего решения по SO или просто гуглил, поэтому любая помощь / понимание будут оценены.

тангентал, но вы действительно хотите сами создавать строки JSON? Предложите использовать библиотеку, такую как Джексон или что-то еще matt b

Ваш Ответ

2   ответа
40

extends работает как для классов, так и для интерфейсов:

private String getListAsJson(List<? extends JsonEnabled> list) { ... }

extends имеет немного другое значение, когда используется для определения общих границ - это по существу означает «есть, или расширяет, или реализует».

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Windle
3

private String getListAsJson(List<JsonEnabled> list) { ... }

?

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Windle
Error: User Rate Limit ExceededUserBuilderError: User Rate Limit ExceededList<User>Error: User Rate Limit ExceededList<User>Error: User Rate Limit ExceededList<JsonEnabled>Error: User Rate Limit ExceededgetListAsJsonError: User Rate Limit Exceeded
Error: User Rate Limit ExceededList<User>Error: User Rate Limit Exceeded

Похожие вопросы