Generics are a compile-time thing. At runtime, a regular ArrayList, without any additional check, is used. Since you’re bypassing the safety checks by using reflection to add elements to your list, nothing can prevent a Double from being stored inside your List<Integer>. Just like if you did
List<Integer> list = new ArrayList<Integer>();
List rawList = list;
rawList.add(new Double(2.5));
If you want your list to implement type checks at runtime, then use
List<Integer> checkedList = Collections.checkedList(list, Integer.class);