I hit a really stupid problem today, and I’ve only got myself to blame (as usual).
The problem was really simple. I was making an object that needed to know when it was created. This creation date wasn’t necessarily “now”, so I was passing a Calendar object in to the constructor of the object to represent the creation date.
The problem was really simple. I was making an object that needed to know when it was created. This creation date wasn’t necessarily “now”, so I was passing a Calendar object in to the constructor of the object to represent the creation date.
Now, the creation date never changes, so I assigned it to a final variable. However, in a momentary lapse of judgement, that’s all I did…
Sure enough, not ten minutes later, I’m looking at an error message in my test and saying “Hmm… it looks like my start date got changed. How did that happen?”. A few seconds of detective work showed that I was keeping a reference to the Calendar object I’d passed in and was changing it a few lines later in the code. D’oh. Of course, the other object with its final reference was looking at the same Calendar value.
Once again, I’d been bitten by the aliasing bug. Hopefully, blogging it will help me rememeber: always be defensive when dealing with mutable objects. And all final does for you is make sure the reference doesn’t change.
(To make it even siller, I’d obtained the original reference from another object, where it was ALSO meant to be final. So I’d actually changed the internals of two objects, both of which were meant to be immutable. Defensive copies also apply when you’re sending mutable data back out into the world…)
This also is inspiring me to remember I need an “unmodifiableCalendar”, similar to the “unmodifiableCollection” that the Collections API gives us. Fortunately, because the Java designers were smart enough to program to types, not classes, this is easy to add. 🙂