4

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 !

J-16 SDiZ
  • 26,473
  • 4
  • 65
  • 84
tomaas
  • 129
  • 1
  • 6

3 Answers3

3

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.

Community
  • 1
  • 1
Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • NICE! Thanks a lot for an answer about instantiating array of generic type. – tomaas Aug 10 '11 at 10:49
  • But what do u mean about compiler catching bug? List l = new ArrayList(); u mean it corrects static type to list because of dinamic type saying Arraylist? – tomaas Aug 10 '11 at 10:50
  • @tomaas, no, I mean just what you observed: the compiler issues warnings (or errors in some cases) to point out (potential) errors in the code. In the case of unchecked warnings, there is almost always a good reason to fix these. However, in some rare cases, when the programmer absolutely knows what (s)he is doing, the unchecked warning may be safely ignored / suppressed. This is one reason why it is not an error (the other is the existence of huge amounts of pre-generic era legacy code). – Péter Török Aug 10 '11 at 11:44
  • @tomaas, the point of static (compile time) error detection is that the compiler must absolutely go through every single line of your code, thus if the code compiles, you can rest assured that there may be no compiler-detectable errors in it. A runtime bug, OTOH, may lay dormant for years in rarely used corners of the code before (if ever) being detected. So no amount of runtime usage or testing can guarantee 100% bug-free code. – Péter Török Aug 10 '11 at 11:48
  • cool, i really appreciate your answers. Seemed like reading a great programming book! :P – tomaas Aug 10 '11 at 20:18
0
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.

djna
  • 54,992
  • 14
  • 74
  • 117
0

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) { }
}
Serabe
  • 3,834
  • 19
  • 24