Question

here is part of tutorial in oracle page :

Consider the following example:

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

In detail, a heap pollution situation occurs when the List object l, whose static type is List<Number>, is assigned to another List object, ls, that has a different static type, List<String> // this is from oracle tutorial

my question would be why is the static type List<Number> and not just List ?? later another question would be from code of my studies :

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>();
}

Why in this code instead of elArray = new ListaConPI[numVertices+1] wouldnt we write elArray = new ListaConPI<Adyacente>[numVertices+1] ?

Thanks a lot !

Was it helpful?

Solution

my question would be why is the static type List<Number> and not just List?

So that the compiler can catch bugs like the above already at compilation time, instead of runtime. This is the main point of generics.

Why in this code instead of elArray = new ListaConPI[numVertices+1] wouldnt we write elArray = new ListaConPI<Adyacente>[numVertices+1]?

Because you can't instantiate arrays of generic types (although you can declare such arrays as variables or method parameters). See this earlier answer of mine to the same question.

OTHER TIPS

List l = // something;

What is the type of l? Its a List, that's its static type, it could be any old List. Hence if you assign

List<String> listOfString = l;

The compiler at compile time cannot know whether this is safe. The example you show demonstrates that it is unsafe, and the ClassCastException results.

Please, read about type erasure. Now, reconsider your code after erasing the types (I'll do only the first example):

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

For the same reason, you cannot have a class like this:

class A<T> {
    public void method(T obj) { }
    public void method(Object obj) { }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top