Те, що ви намагаєтеся зробити, дуже корисно, і я вважаю, що мені потрібно це робити дуже часто в коді, який я пишу. Приклад використання:
Скажімо, у нас є інтерфейс, Fooі у нас є zorkingпакет, ZorkingFooManagerякий створює і управляє екземплярами пакет-приватний ZorkingFoo implements Foo. (Дуже поширений сценарій.)
Отже, ZorkingFooManagerповинен містити, private Collection<ZorkingFoo> zorkingFoosале його потрібно виставити public Collection<Foo> getAllFoos().
Більшість програмістів Java не замислювалися б двічі перед тим, getAllFoos()як реалізувати, як виділити нове ArrayList<Foo>, заповнивши його всіма елементами zorkingFoosта повернути його. Мені подобається розважати думку про те, що приблизно 30% усіх циклів годин, що споживаються кодом java, який працює на мільйонах машин по всій планеті, не робить нічого, крім створення таких марних копій ArrayLists, які після їх створення збирають сміття мікросекундами.
Вирішення цієї проблеми - це, звичайно, колекціонування колекції. Ось найкращий спосіб зробити це:
static <T,U extends T> List<T> downCastList( List<U> list )
{
return castList( list );
}
Що приводить нас до castList()функції:
static <T,E> List<T> castList( List<E> list )
{
@SuppressWarnings( "unchecked" )
List<T> result = (List<T>)list;
return result;
}
Проміжна resultзмінна необхідна через збочення мови java:
return (List<T>)list;створює виняток "неперевірений ролик"; все йде нормально; але з іншого боку:
@SuppressWarnings( "unchecked" ) return (List<T>)list; - незаконне використання анотації придушення-попередження.
Отже, навіть якщо це не кошерніше використовувати @SuppressWarningsв returnоператорі, це, мабуть, добре використовувати його у призначенні, тому додаткова змінна "результат" вирішує цю проблему. (У будь-якому випадку його слід оптимізувати або компілятором, або JIT.)