I have this demo, which I dont need a particular solution with a redrawn architecture, but just understanding why behaves like that and any thing I am missing for avoiding it. I am wondering why:
- Compiler allows the insertion of an element that its not the type of the list into the list
-
The ClassCast exception is thrown when we try to get the element instead of when pushing it
import Test.*; //Inner classes import java.util.List; import java.util.ArrayList; public class Test<E extends Object> { private List<E> list = new ArrayList<E>(); public Test() {} public static void main(String[] args) { Test<String> a = new Test<String>(); a.addElement(new String()); a.addElement(new Integer(0)); // No complain in comp/run-time, I dont understand why CastException is not thrown here String class1 = a.getElement(0); String class2 = a.getElement(1); //No complain in comp but ClassCastException: Integer cannot be cast to String //Integer class3 = a.getElement(1); //Compilation error } public void addElement (Object node) { list.add((E) node); } //No complain in comp/run-time public E getElement(int index) { return list.get(index); } }
What could be a solution? Notice the line addElement where I need to pass a SuperClass, instead of type E. This is needed for my architecture, this is just a simple mock demo. But anyway the casting to type E should act as desired and throw a CastExeption in runtime, should not?
The problem is
(E) nodedoesn’t do run-time type check due to type erasure. All the information about generic types is lost after compilation.Java compiler should warn you about it:
You can do this check manually by using reference to java.lang.Class: