It is known that arraylist init. should be like this
ArrayList a = new ArrayList();
ArrayList a = new ArrayList
A lot of this has to do with polymorphism. When you assign
X = new Y();
X can be much less 'specific' than Y, but not the other way around. X is just the handle you are accessing Y with, Y is the real instantiated thing,
You get an error here because Integer is a Number, but Number is not an Integer.
ArrayList a = new ArrayList(); // compile-time error
As such, any method of X that you call must be valid for Y. Since X is more generally it probably shares some, but not all of Y's methods. Still, any arguments given must be valid for Y.
In your examples with add, an int (small i) is not a valid Object or Integer.
ArrayList> a = new ArrayList>();
This is no good because you can't actually instantiate an array list containing ?'s. You can declare one as such, and then damn near anything can follow in new ArrayList