Java's generics don't actually change the underlying class or object, they just provide (mostly) compile-time semantics around them.
By passing an ArrayList<Integer> into a method expecting an ArrayList (which can hold anything), you're bypassing the compiler's ability to provide you with that type safety.
The Java Generics Tutorial explains this, and why Java implements generics this way. This page, in particular, focusses on it:
Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:
- Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
- Insert type casts if necessary to preserve type safety.
- Generate bridge methods to preserve polymorphism in extended generic types.
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
What that doesn't say is that this also allows code written with generics (like your run) to interact with code written without generics (like your readList), which is important when adding a feature to a very-well-established language with a huge library base (as they were when adding generics to Java).
Rawtype inreadList(). 2. Read abouttype erasure.List. You are retrieving the type of the first element of theList.readList(list), it's actually adding things into list that are 'falsely' regarded as typeArrayListso there is no error. But if I do callprintln("Type of list = "+list.get(0).getClass());inrun()there comes the error. Is it like some criminal escaped from crime scene at first (because he belongs to normal people and normal people has freedom), and when police start to check everyone that was around then he got caught because he is a criminal in deep?