I am reading about Generics in Effective Java item 23. It is mentioned as below:
While the prospect of accidentally inserting a coin into a stamp collection may appear far-fetched, the problem is real. For example, it is easy to imagine someone putting a
java.util.Date
instance into a collection that is supposed to contain onlyjava.sql.Date
instances.
I am not able to understand what does author mean by "it is easy to imagine someone putting a java.util.Date
instance into a collection that is supposed to contain only java.sql.Date
instances"?
Collection<java.util.Date> dateColl = new ArrayList();
String strDate = "2011-12-31 00:00:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
java.util.Date date = sdf.parse(strDate);
java.sql.Date sqlDate = new Date(date.getTime());
dateColl.add(sqlDate);
Why above code is not throwing compilation error?
I am not able to understand what does author mean by "it is easy to imagine someone putting a java.util.Date instance into a collection that is supposed to contain only java.sql.Date instances"?
In your example :
Collection<java.util.Date> dateColl = new ArrayList();
java.util.Date date = sdf.parse(strDate);
...
dateColl.add(date);
you do the reverse. You declare a Collection of java.util.Date
. And besides you have added a java.util.Date
instance in the collection of java.util.Date instance
. You never use the java.sql.Date
instance you declare and of course adding a java.util.Date
instance in a collection of java.util.Date
doesn't require any cast and doesn't question about type compatibility.
In a OOP point of view : a java.sql.Date
IS a java.util.Date
type. So, it is legal :
Collection<java.util.Date> dateColl = new ArrayList();
dateColl.add(new java.sql.Date(...));
To understand the problem, you should declare :
Collection<java.sql.Date> dateColl = new ArrayList();
and then try to add a java.util.Date instance. There, you will have a compilation problem since "you are putting a java.util.Date instance into a collection that is supposed to contain only java.sql.Date instances".
Without using generics in Collection classes, the compilation will not fail and therefore at the runtime, you may have ClassCastException
if you expect to have a collection which contains only java.sql.Date
instances :
Here, you will have a ClassCastException
in the loop since you could not cast the java.util.Date
instance to a java.sql.Date
instance :
Collection mySqlDates = new ArrayList();
mySqlDates.add(new java.sql.Date(...));
mySqlDates.add(new java.util.Date(...));
for (Object object : mySqlDates) {
java.sql.Date sqlDate = (java.sql.Date) object;
}