All entries for Thursday 20 April 2006
April 20, 2006
Crappy java.sql.Timestamp pretending to be java.util.Date
So I started getting ClassCastExceptions when comparing two java.util.Dates. Tracking it down, I realised (and in fact the stack trace told me) that one of the java.util.Dates was actually a java.sql.Timestamp. So looking at the code, I was a bit surprised to realise that I was actually casting the objects to java.util.Date….which is valid because java.sql.Timestamp extends java.util.Date.
So why doesn't it work, and whose fault is it?
On the face of it, it would appear java.util.Timestamp is at fault because it is a java.util.Date and should therefore be able to be used in place of a java.util.Date; quite a fundamental OO rule (substitution). But then thinking a bit more, I realised it isn't quite so clear cut... The substitution rule states that you must be able to use any subclass in place of it's parent, but it doesn't state that the sub class must behave exactly like it's parent...which is obvious when you think about it. If this wasn't the case, you would never be allowed to change the behaviour of any of the methods. Arguably, you should never make the behaviour inconsistent with the intention of the super classes' method.
In otherwords, java.util.Date.compareTo(java.util.Timestamp) must work, but there is no guarantee that java.util.Timestamp.compareTo(java.util.Date) needs to work..
And in fact, it was java.sql.Timestamp.compareTo(java.util.Date) was throwing the exception.
So it seems java.sql.Timestamp is technically correct, even if it isn't very friendly :(
Still think it is wrong, but not sure it is technically wrong…..