В общем, вы должны поддерживать интерфейсы над абстрактными классами. Одной из причин использования абстрактного класса является то, что у вас есть общая реализация среди конкретных классов. Конечно, вы все равно должны объявить интерфейс (IPet) и иметь абстрактный класс (PetBase), реализующий этот интерфейс. Используя небольшие, четкие интерфейсы, вы можете использовать множественные числа для дальнейшего повышения гибкости. Интерфейсы обеспечивают максимальную гибкость и переносимость типов через границы. При прохождении ссылок через границы всегда передавайте интерфейс, а не конкретный тип. Это позволяет принимающей стороне определить конкретную реализацию и обеспечивает максимальную гибкость. Это абсолютно верно при программировании в режиме TDD / BDD.
The Gang of Four заявили в своей книге «Поскольку наследование предоставляет подкласс для подробностей реализации его родителя, часто говорят, что« наследование прерывает инкапсуляцию », , Я считаю, что это правда.
Вы можете использовать решение Божо, или избежать создания временного списка массивов, используя:
Class<List<MyClass>> clazz = (Class) List.class;
Единственная проблема с этим решением в том, что вы должны подавить предупреждение unchecked с помощью @SuppressWarnings("unchecked").
Если Вы используете SpringFramework
, Вы могли бы использовать ParameterizedTypeReference
следующим образом:
restClient.getDeserializedJSON(ParameterizedTypeReference<List<MyClass>>(){},url);
В дополнение к этому я нашел вот это в документации Gson.
Type listType = new TypeToken<List<String>>() {}.getType();
Что решает проблему безопасного получения типа, но класс TypeToken специфичен для Gson.
Вы не можете. Вам придется использовать небезопасное приведение:
Class<List<MyClass>> clazz =
(Class<List<MyClass>>) new ArrayList<MyClass>().getClass();