4

这是 oracle 页面中教程的一部分:

考虑以下示例:

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<Number>详细来说,当静态类型为 的 List 对象 l被分配给另一个具有不同静态类型的 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]

非常感谢 !

4

3 回答 3

3

我的问题是为什么是静态类型List<Number>而不仅仅是List

这样编译器就可以在编译时而不是运行时捕获上述错误。这是泛型的要点。

为什么在这段代码中而不是elArray = new ListaConPI[numVertices+1]我们不会写elArray = new ListaConPI<Adyacente>[numVertices+1]

因为您无法实例化泛型类型的数组(尽管您可以将此类数组声明为变量或方法参数)。请参阅我对同一问题的较早回答

于 2011-08-10T10:28:11.030 回答
0
List l = // something;

l 的类型是什么?它是一个 List,这是它的静态类型,它可以是任何旧的 List。因此,如果您分配

List<String> listOfString = l;

编译器在编译时无法知道这是否安全。您展示的示例表明它是不安全的,并且 ClassCastException 结果。

于 2011-08-10T10:28:32.233 回答
0

请阅读有关类型擦除的信息。现在,在删除类型后重新考虑你的代码(我只会做第一个例子):

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) { }
}
于 2011-08-10T10:29:11.250 回答