I think "List L=new ArrayList<Integer>();" will first create a Arraylist of Integer typed class then upcast to the type of Object, which is default. but whenever you are trying like "List<Integer> L=new ArrayList();" it will try to create a Object typed ArrayList first then try to set them into a Integer type List.
In first case it will compile and show a warnning conserning about you list is no more type-safed. But in second case compiler will generate an error.
This does not generate a compiler error, just a warning, though.
This is like this because Java did not have generics until JDK1.5, and they wanted that legacy code were compatible with new generics code. Therefore, if you had libraries returning raw types or receiving raw types as parameters, the Java Programming Language should still work.
This practice though is not recommended for new code written for JDK15 or superior. What you did should have been done like this
A list like this can accept any kind of list and since it uses an unbounded wildcard it will not generate a warning, as it does your legacy code.