2016-07-27 2 views
3

У меня вопрос о дженериках.Ошибка компиляции дженериков с ограничениями

У меня есть этот фрагмент кода внутри класса (назовем его случай 1):

static { 
    final List<Class<? extends A>> typeList = Arrays.asList(
     C.class, 
     D.class 
    ); 
} 

и

public interface A {…} 

public class C extends B {…} 

public class D extends B {…} 

public abstract class B implements A {…} 

Android Студия жалуется и не компилируется на линии final List… выше:

Несовместимые виды
Обязательный список < Класс <? extends A > >
Найдено < Класс <? расширяет Аргументы B > >

Но раньше у меня был этот код (давайте назовем это случай 2):

static { 
    final List<Class<? extends A>> typeList = Arrays.asList(
     C.class, 
     D.class 
    ); 
} 

и

public interface A {…} 

public class C implements A {…} 

public class D implements A {…} 

и он составлен.

Итак, я попробовал, только ради сужая проблему, изменение регистра 1 в этом:

static { 
    final List<Class<? extends A>> typeList = Arrays.asList(
     B.class 
    ); 
} 

Пожалуйста, обратите внимание, что B реализует A, так же, как C и D в случае двух. Но компилятор все еще жалуется.

У меня нет идей, чтобы понять эту проблему, я читал главу «Типы и ценности» и все еще ничего.

Я искал в StackOverflow, и я не нашел аналогичного вопроса.

Любые указатели? (PS: обязательно XKCD перед тем, как кто-то это сделает)

+0

Компиляция отлично подходит для меня. Вы можете использовать явный аргумент типа, если используете Java 7. –

+0

Sotiros Delimanolis, это действительно дубликат этого вопроса, я предполагаю, что раньше я использовал неправильные термины для поиска. –

ответ

6

Проблема - проблема вывода типа. До Java 8 компилятор не был достаточно умен в своем умозаключении для использования типа typeList при определении экземпляра Arrays.asList, так что это происходит изолированно.

Попробуйте это явный намек:

final List<Class<? extends A>> typeList = Arrays.<Class<? extends A>>asList(
    B.class 
); 

Чтобы перейти в более подробно, компилятор просто видит это в изоляции:

Arrays.asList(
    C.class, 
    D.class 
); 

, не видя, что он назначен. Он выбирает Class<? extends B> вместо Class<? extends A>, так как это самый конкретный супертип, общий для всех аргументов.

+0

Whoa.Хороший. – Mena

+0

Он работал безупречно! Вы были быстры, поэтому быстрый StackOverflow не позволит мне принять его еще! Спасибо, Марк Петерс. –

Смежные вопросы