2012-02-09 2 views
0

Я готовимся к OCJP. Я нашел вопрос отвалакак функция реализует Generics в java

import java.util.*; 
public class G1 { 
public void takeList(List<? extends String> list) { 
    // insert code here 
} 
} 

Какие три фрагмента кода, вставленного независимо друг от друга на линии 6, будет компилировать? (Выберите три.)

A. list.add("foo"); 
B. Object o = list; 
C. String s = list.get(0); 
D. list = new ArrayList<String>(); 
E. list = new ArrayList<Object>(); 

Ответ: B, C, D

У меня есть запрос, если List<? extends String, что означает, что он совпадает с классом Струнного и всего подклассом класса String.

Может ли кто-нибудь обосновать ответ, показанный здесь?

+7

java.lang.String является окончательным классом. – adatapost

+1

вариант A также действителен, я думаю, –

+0

Я попытался запустить код опции A дает ошибку – coder25

ответ

4

А неверен, потому что ваш список может быть List<SomeStringSubClass>, и поэтому было бы недействителен, чтобы добавить строку к нему , (Я знаю, что String является окончательным, но компилятор здесь не заботится).

E неверен, потому что List<Object> не могут быть отнесены к List<? extends String>, очевидно, так как объекты, содержащиеся на List<Object> не обязательно имеют тип String, или подкласса String.

Остальные три из них в порядке:

  • B в порядке, потому что все, кроме примитивов является объект в Java
  • C в порядке, потому что List<? extends String> содержит экземпляры строки, или экземпляры подкласса Строка. И экземпляр подкласса также является экземпляром суперкласса.
  • D в порядке, потому что ArrayList<String> является List<String> и List<String> также List<? extends String>
+0

Я не могу понять, почему list.add ("foo") не может быть использован.Can u hep – coder25

+0

Давайте возьмем пример с чем-то другим, кроме String. «Список 'означает" Список какого-либо класса, который является Animal или расширяет Animal, но мы не знаем, какой тип ". Таким образом, это может быть «Список » или «Список » или «Список ». Если это «Список », и вы можете сделать «list.add (новый Chicken())» или «list.add (новый Animal())», тогда безопасность типов списка полностью нарушена, поскольку он должен содержать только экземпляры Собаки. Таким образом, это незаконно. –

+0

Но если проблема безопасности типа является проблемой, то почему List . Может быть просто List coder25

0

List является Object, поэтому B действителен.

Все, что хранится в списке, может быть вырождено до строки, и поэтому C действителен.

В дженериков «<? extends String>» охватывает подклассы String, из которых Есть ни один, сам по себе и String, поэтому D не является действительным.

Аналогичным образом, "<? super String>" означает String или любое из String's деревьев наследования, например. Object, CharSequence, Serializable и т.д.

1
A. `list.add("foo");` 

не будет компилировать, как вы сможете только вставить null в этот список

B. Object o = list; 

Собирает, так как список является объектом

C. String s = list.get(0); 

Скомпилирует, поскольку каждый элемент в списке гарантированно является строковым объектом или теоретическим подклассом (практически невозможно s String - последний класс и не может быть расширен).

D. list = new ArrayList<String>(); 

Скомпилирует, так как каждый элемент в списке, как гарантируется, является строковым объектом.

E. list = new ArrayList<Object>(); 

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

Keep in mind that String is a final class and cannot be extended. 
0

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

Более простой пример

public void takeList(List<? extends Number> list) { 
    // insert code here 
    list.add(1.0); // not allowed. 
    Number n = list.get(0); // allowed. 
} 

// you could call it with 
takeList(new List<BigInteger>());