问题
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 !
回答1:
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.
回答2:
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.
回答3:
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