четверг, 24 марта 2011 г.

Complex Generics

Недавно узнал решение для следующей задачи:
  1. Имеется класс С
  2. Имеется интерфейс I
  3. Нужно написать generic класс с параметром, который одновременно расширяет C и реализует I
Наивное решение:
class K<T extends C implements I>
приводит к очень невразумительным ошибкам компилятора: он не ругается на эту строку, но при этом считает, что K должен implements I.
А правильный вариант другой:
class K<T extends C & I>

Такой вот любопытный синтаксис. Это описано в разделе Converting Legacy Code to Use Generics. Там же указано, что интерфейсов можно задать сколько угодно:
class K<T extends C & I1 & I2 & ...>

2 комментария:

  1. Может, засабмитить какой-то импрувмент на эту тему? чтобы 'implements' тоже понимало.

    ОтветитьУдалить
  2. Я думаю, что так сознательно сделано.
    Если ты пишешь <T extends C>,
    то это не значит, что тип T должен расширять класс C, а просто должен к нему каститься. Кроме того, C может быть не классом, а интерфейсом. Они взяли подходящий keyword, а вместо запятой использовали знак &. Кстати, могли бы использовать двоеточие вместо extends:
    <T: C1 & C2 & C3>

    ОтветитьУдалить