Reputation: 495
List<String> v = new ArrayList<String>();
I understand the generics helps you declare that the ArrayList() has Objects of type String. My question is how is the following one different from the above?
List<String> v = new ArrayList();
or the one below different from others
List v = new ArrayList<String>();
Upvotes: 3
Views: 342
Reputation: 328923
public static void main(String[] args) throws Exception {
List<String> list1 = new ArrayList<String>();
List<String> list2 = new ArrayList(); //This is equivalent to list1 but with compilation warning
List list3 = new ArrayList<Integer>(); //This is equivalent to list3 = new ArrayList<Object>()
//list1.add(new Object()); //does not compile
//list2.add(new Object()); //does not compile
list3.add(new Object()); //this is fine
list1 = list3; //ok, but
System.out.println(list3.get(0)); // this is fine
System.out.println(list1.get(0)); //Runtime error: ClassCastException
//List<Object> list5 = list1; //does not compile
List<Object> list5 = list3; //ok
}
Upvotes: 1
Reputation: 47994
List<String> v = new ArrayList();
This one isn't really functionally different. The type parameter on the right side doesn't really do anything. It's used as a matter of style and to avoid the use of a Raw type, which is considered a programming error. In fact, in Java 7 it has been enhanced so you can just do this: List<String> v = new ArrayList<>();
and not have to repeat yourself on the right hand side.
List v = new ArrayList<String>();
The list with no type parameter is called a Raw Type. It is generally considered a programming error to declare a Raw Type in new code that is using generics. Basically there is no type checking going on at all when you declare it this way, you can put anything in that list.
Java generics are a compile time check. So it is the type of the reference at compile time that matters. If your reference is of type Raw List
it doesn't matter what you declared on the right hand side, that is what the compiler will check against.
List<String>
isn't really a "List that has Strings." It is a "List that I have asked the compiler to return errors and/or warn me if I put something in there that isn't a String. If you ignore compiler warnings, it is perfectly possible to get stuff in there that isn't a String.
Upvotes: 4
Reputation: 1646
List v = new ArrayList();
It is before java 5 way of declaring a list.
List<String> v = new ArrayList<String>();
It uses generics, introduced in java 5. It adds compile-time type safety.
List<String> v = new ArrayList<>();
is just an optimization introduced in java 7. It just simplifies the code by maintaining the type safety
Upvotes: 1
Reputation: 28802
In the first and third case (new ArrayList<String>()
) you instantiate an ArrayList
that can hold String
instances
In the second case (new ArrayList()
) you instantiate an ArrayList
that can hold Object
instances (that is instances of any type -- even mix & match)
In the first and second case (ArrayList<String> v
) you declare an instance of ArrayList
that can hold String
instances
In the third case (ArrayList v
) you declare an instance of ArrayList
that can hold instances of Object
.
The problem with the second case is that if you were to get hold of a "raw" ArrayList
(like the one instantiated), then it could hold anything theoretically; not just String
instances, which is what the users of the declaration expect.
Similarly, in the third case, you create an ArrayList
that is supposed to hold String
s, but the users of the declaration do not know that and might try to put other object instances in it
Note: of course under the hood, in the JVM, the generic type information is lost, so there are no differences in terms of execution, but for programming type safety, the compiler will flag the incorrect use. This way, there is no need to dynamically check/ensure the type of the objects put into/coming out of the list -- you can assume they are the correct type, because the compiler ensured this
Upvotes: 0
Reputation: 21269
These all compile, and are all valid. The second case is likely only going to throw a warning - you won't be able to add anything that isn't a string due to List<String>
. In the third case you have the opposite problem. You CAN add things that aren't Strings, but may run into a runtime exception as a result.
Upvotes: 0