2016-07-13 3 views
-1
public class HelloWorld{ 

public static void main(String[] args) { 

    List<? extends Number> callback = new ArrayList<Long>(); 
    new Container<>().test(callback); 
} 

public static class Container<T extends Number> { 

    public void test(List<T> some) { 

    } 

} 

}Дженерики - несовместимые типы

этот код производит

HelloWorld.java:7: error: incompatible types: List<CAP#1> cannot be converted to List<Number>                                       
     new Container<>().test(callback);                                                    
          ^                                                      
    where CAP#1 is a fresh type-variable:                                                     
    CAP#1 extends Number from capture of ? extends Number 

Можете ли вы объяснить в деталях этот код неверен.

Я ожидаю, что новый контейнер будет обобщен с типом, совместимым с обратным вызовом

+3

Несколько бессмысленно, так как 'String' является' final' классом. – Bohemian

+1

@Bohemian представьте, что это номер – gstackoverflow

+0

В этом случае используйте 'Number', так как есть веские причины использовать' Number' в generics, но не очень много для 'String'. – Makoto

ответ

1

Во-первых, не может быть типом, который расширяет String в String является конечный класс.

Во-вторых, компилятор не может определить, является ли тип ? extends SomeType, который вы используете для List того же типа, как T extends SomeType, который вы используете для Container класса, поэтому он выдает ошибку.

Что вам нужно будет сделать, это либо объявить общий тип в сигнатуре метода и использовать этот тип для обоих List и Container:

public <T extends SomeClass> void example() { 
    List<T> callback = new ArrayList<>(); 
    new Container<T>().test(callback); 
} 

Или объявить список с не ограниченным типа:

List<SomeClass> callback = new ArrayList<>(); 
new Container<>().test(callback); 
+0

да, это правда +1 –

+0

Я думаю, вы имели в виду * объявить список с неограниченным типом *, нет? – Bohemian

+0

@Bohemian да, мой плохой – explv

0

Ну, вы используете дженерики. как вы определяете Container, он сообщает, что конструктор по умолчанию Container должен поддерживать тип, который является экземпляром String. вот правильный пример, который String является подклассом Object, поэтому я использую это.

public class HelloWorld{ 

    public static void main(String[] args) { 

     List<String> callback = new ArrayList<String>(); 
     new Container<String>().test(callback); 
    } 

    public static class Container<T extends Object> { 

     public void test(List<T> some) { 

     } 

    } 
} 

Надеюсь, это вам поможет.

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