дженерики Java, непроверенные предупреждения - PullRequest
4 голосов
/ 10 августа 2011

вот часть урока на странице оракула:

Рассмотрим следующий пример:

List l = new ArrayList<Number>();
List<String> ls = l; // unchecked warning
l.add(0, new Integer(42)); // another unchecked warning
String s = ls.get(0); // ClassCastException is thrown

Подробно, ситуация загрязнения кучи возникает, когда объект List l, статический тип которого List<Number>, назначен другому объекту List, ls, который имеет другой статический тип List<String> // это из oracle учебник

мой вопрос: почему статический тип List<Number>, а не просто List ?? позже другой вопрос будет из кода моих исследований:

public class GrafoD extends Grafo {

protected int numV, numA;
protected ListaConPI<Adyacente> elArray[];

*/** Construye un Grafo con un numero de vertices dado*
* @param numVertices: numero de Vertices del Grafo
*/
@SuppressWarnings("unchecked")
public GrafoD(int numVertices){
numV = numVertices; numA=0;
elArray = new ListaConPI[numVertices+1];
for (int i=1; i<=numV; i++) elArray= new LEGListaConPI<Adyacente>();
}

Почему в этом коде вместо elArray = new ListaConPI[numVertices+1] мы не можем написать elArray = new ListaConPI<Adyacente>[numVertices+1]?

Большое спасибо!

Ответы [ 3 ]

3 голосов
/ 10 августа 2011

мой вопрос: почему статический тип List<Number>, а не просто List?

Чтобы компилятор мог отлавливать ошибки, подобные описанным выше, уже во время компиляции, а не во время выполнения. Это основной смысл дженериков.

Почему в этом коде вместо elArray = new ListaConPI[numVertices+1] мы не будем писать elArray = new ListaConPI<Adyacente>[numVertices+1]?

Потому что вы не можете создавать экземпляры массивов универсальных типов (хотя вы можете объявлять такие массивы как переменные или параметры метода). См. мой более ранний ответ на тот же вопрос .

0 голосов
/ 10 августа 2011

Пожалуйста, прочитайте о типе стирания . Теперь пересмотрите ваш код после стирания типов (я сделаю только первый пример):

List l = new ArrayList(); // Compiler remembers that it should check that only numbers can be added
List ls = l; // Compiler remembers that it should cast everything back to a String
l.add(0, new Integer(42)); // the compiler checks that the second parameter is a Number.
String s = ls.get(0); // The compiler casts the result back to a String, so you get an exception

По той же причине у вас не может быть такого класса:

class A<T> {
    public void method(T obj) { }
    public void method(Object obj) { }
}
0 голосов
/ 10 августа 2011
List l = // something;

Какой тип л? Это список, это его статический тип, это может быть любой старый список. Следовательно, если вы назначите

List<String> listOfString = l;

Компилятор во время компиляции не может узнать, безопасно ли это. Показанный вами пример демонстрирует, что это небезопасно, и приводит к исключению ClassCastException.

...