2 апреля 2013 г.

Обобщённое приведение интерфейса к реализации

Предположим, у вас есть объект, реализующий некий интерфейс и вы ожидаете, что этот объект на самом деле имеет вполне конкретную реализацию. Тогда вы можете воспользоваться следующим обобщённым (generic) методом, чтобы привести его к конкретном типу:

public <T> T castToImplementation(Object element, Class<T> implClass) {
if (!implClass.isInstance(element)) {
throw new IllegalArgumentException("Illegal implementation");
}
return implClass.cast(element);
}
Пусть Group - некий интерфейс, а GroupImpl - его реализация, и вы хотите привести интерфейс к реализации. Пример использования:
// Group element = ...
GroupImpl groupImpl = castToImplementation(element, GroupImpl.class);
Хотелось бы отметить, что подобное приведение нарушает принципы ООП, однако в отдельных случаях это может быть оправдано. Например, в приложении типа "клиент-сервер", где заранее известно, что может быть только одна реализация интерфейса.

Как получить все значения enum

Все значения enum (перечисления) в java можно получить при помощи метода values(). Затем по этим значениям можно, например, пройтись в цикле и что-нибудь с ними сделать. Рассмотрим пример: SomeEnum - это некий созданный нами enum со значениями. Отобразим все имена этих значений в нижнем регистре:
for (SomeEnum en : SomeEnum.values()) {
System.out.println(en.name().toLowerCase());
}
А вот и универсальный метод, который может отобразить все значения любого enum:
public <E extends Enum<E>> void displayEnumMembers(Class<E> en)
{
for (E a : en.getEnumConstants()) {
System.out.println(a.name().toLowerCase());
}
}
Здесь используется обобщённый (generic) метод. Запись E extends Enum<E> означает, что E - это класс Enum или его наследник. E - просто обозначение - вы можете использовать любую другую букву. Метод принимает на вход экземпляр типа Class, типизированный конкретным классом перечисления. Пример вызова метода:
displayEnumMembers(SomeEnum.class);