Below is the code,
import java.util.List;
import java.util.ArrayList;
public class Dummy {
public static void main(String[] args) {
List lst = new ArrayList();
lst.add("a string");
lst.add("another string");
String s = lst.get(0);
} //end main
}
when the constructor new ArrayList(); is invoked, array of type Object is created.
..
lst holds Object[0] array.
So, If array of type Object gets created by constructor, How does javac does not see type casting issue in this statement String s = lst.get(0);, despite generic syntax is used while invoking constructor?
解决方案
Here is some non-generic code:
public class MyList {
List myData = new ArrayList();
public void add(Object ob) {
myData.add(ob);
}
public Object getAtIndex(int ix) {
return myData.get(ix);
}
}
This code will allow you to store an object of any type into your MyList instances even if the contract of MyList specifies that the objects must all be of the same type. Moreover if you use a MyList instance to store String instances, you must manually cast them to String when you retrieve them.
String myString = (String) myList.get(1);
The above MyList class is not type safe. It is most definitely possible that the above assignment statement will fail with a ClassCastException if an object other than a String instance was stored into your MyList instance (which can happen at run-time without any complaint).
Here is a generified MyList class:
public class MyList {
List myData = new ArrayList<>();
public void add(T ob) {
myData.add(ob);
}
public T getAtIndex(int ix) {
return myData.get(ix);
}
}
Now, the compiler guarantees that only T instances can be added and retrieved from MyList instances. Because the compiler guarantees that T instances will always be returned, you can use syntax like this without any manual casting:
String myString = myList.get(1);
The generified MyList class is now type-safe. The compiler won't allow you to store anything but T instances into your MyList instances, which guarantees that no ClassCastExceptions will occur at run-time. If you examine the byte-code, you'll find that the compiler has placed a cast automatically.
Generics in Java are a compile-time only phenomenon. In the byte-code, all references to T in the MyList class above are replaced by Object. This process is referred to as "type erasure". It is important to remember that type safety in Java is provided by the compiler only. If your program compiles without any errors AND without any warnings, then your program, generics and all, is type safe. The compiled program, however, has retained almost no information about the generic parameters.