2010-03-04 3 views
1

У кого-нибудь есть хорошее объяснение, почему синтаксис ? extends должен использоваться в дженериках? Я знаю, что синтаксис применяется, но он просто не согласуется с тем, как проверка не общего типа выполняется на Java. Например:Зачем вам нужно «? Extends» в generics

void someMethod() { 
    List<String> strings = new ArrayList<String>(); 
    doSomethingWithStrings(strings); 
    doSomethingWithObjects(strings); // << This doesn't compile 
} 

void doSomethingWithStrings(Collection<String> strings) {} 

void doSomethingWithObjects(Collection<Object> objects) {} 

Это будет иметь ошибки компиляции, где комментировал, в то время как в следующем примере нет, очевидно, нет ошибки компиляции:

void someOtherMethod() { 
    String string = "worksInBothPlaces"; 
    doSomethingWithAString(string); 
    doSomethingWithAObject(string); 
} 

void doSomethingWithAString(String string) {} 

void doSomethingWithAObject(Object object) {} 

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

void doSomethingWithObjects(Collection<? extends Object> objects) {} 

, но опять же, что не похоже на проверку типа, выполняется в другом месте. Есть ли какой-то ясный пример, где без ? extends некоторого родового класса было бы сложнее или даже невозможно писать.

+1

По аналогичным вопросам/ответам см. Http://stackoverflow.com/search?q=java+covariance –

ответ

3

В основном общий не может подтвердить материал перераспределения.

void AddSomething(Collection<Stuff> object) 
{ 
    object.Add(new Stuff()); 
} 

потерпит неудачу, если вы пытаетесь вызвать

AddSomething(new Collection<ChildStuff>()) 

, потому что вы не можете добавить товар в коллекции ChildStuff.

Для компилятора/времени выполнения/независимо от того, что ваша функция не будет делать ничего подобного, нужно сказать, что приемлемо принимать подтипы, и это делается с помощью синтаксиса ? extends.

+0

А, это то, что имеет для меня прекрасный смысл. Я знал, что будет простой пример, о котором я не думал. благодаря – Yanamon

1

Проще говоря, поскольку Collection<String> - это не тот же тип, что и Collection<Object>, и он тоже не является подтипом.

Это Collection<String>неCollection<Object>, где, как StringявляетсяObject.

Деталь относительно того, почему это так, довольно сложно, и вам будет лучше всего обратиться к Angelika Langer's FAQ по дженерикам в Java.

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