The first example is correct, you supply everything needed. But it also means you repeat the definition of the parameter type.
Then, in Java 1.7 (or maybe 1.8, not quite sure) they introduced the shortened version - so in case you define ArrayList<Integer> numbers
, there is no need to define repeat that ArrayList
for Integer
should be created and you just keep <>
there. This is sometimes called a diamond notation and instructs compiler to use the very same data type that you used for the field definition. So, as a result it behaves exactly like the first example, but without the need to duplicate the information about data type.
The last case you have there is somewhat different as you create an ArrayList
of no specified data type. This can be somewhat dangerous as it allows you to write the following code:
List listAnything = new ArrayList();
listAnything.add("string");
listAnything.add(42);
listAnything.add(false);
List<Integer> listInteger = listAnything;
The above listed code compiles perfectly fine, though there are some warnings about unchecked conversions and using raw types. You are no longer to guarantee that listInteger
contains only integers.
Also, word of warning here - you should rely on abstraction as much as possible in your code. By this I mean to define your fields using an interface or an abstract class rather than concrete one. Such a code is a significantly better to read and to maintain:
ArrayList<Integer> list = new ArrayList<>(); // this is not wrong...
List<Integer> list = new ArrayList<>(); // ...but this is better