Как вы можете передать список <объекты, реализующие интерфейs>, методу?

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

public String getAsJson(){...}

И у сервлета есть куча в основном indentical методов, которые выглядят так:

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(), сделать каждый bean реализованным, а затем использовать другой метод в сервлете, который взял объекты, которые реализовали этот интерфейс. Закончилось так:

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, а не внедрять для общих параметров. Выделение всех классов из абстрактного класса, который имеет только метод getAsJson(), не имеет смысла семантически (классы не связаны).

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

Ответы

Ответ 1

Для общих подстановочных знаков ключевое слово extends работает как для классов, так и для интерфейсов:

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

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

Ответ 2

Почему бы просто не использовать

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

?