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 !
my question would be why is the static type
List<Number>
and not justList
?
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 writeelArray = 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.
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) { }
}
来源:https://stackoverflow.com/questions/7009226/java-generics-unchecked-warnings