java.util.Date clone or copy to not expose internal reference

JavaClone

Java Problem Overview


It is best practice not to expose the internal references of an Object (Entity). So if an Object has a field of type java.util.Date then for example the getter for this field should return not the original date but an copy of it.

But for an java.util.Date there are two common ways to create that copy:

  • clone: (Date) originalDate.clone()
  • copy via constructor new Date(originalDate.getTime())

My question is, which way is better, and why?

Java Solutions


Solution 1 - Java

If it's definitely just a Date, it won't make any difference either way.

If the actual object might be a subclass of Date (such as java.sql.Date) then I'd hope that clone() would preserve the extra information (including which class it is) whereas calling the constructor wouldn't.

As an aside, if you used Joda Time you wouldn't have this problem, as there are plenty of immutable types to use. It's also a much better API :)

Solution 2 - Java

Read Effective Java. The preferred way to create copies is to use the copy constructor approach.

> Bill Venners: In your book you recommend using a copy constructor > instead of implementing Cloneable and writing clone. Could you > elaborate on that? > > Josh Bloch: If you've read the item about cloning in my book, > especially if you read between the lines, you will know that I think > clone is deeply broken. There are a few design flaws, the biggest of > which is that the Cloneable interface does not have a clone method. > And that means it simply doesn't work: making something Cloneable > doesn't say anything about what you can do with it. Instead, it says > something about what it can do internally. It says that if by calling > super.clone repeatedly it ends up calling Object's clone method, this > method will return a field copy of the original.

Solution 3 - Java

If you're coding defensively, you'll want the copy constructor. See this passage from Effective Java:

> Note also that we did not use Date's clone method to make the defensive copies. Because Date is nonfinal, the clone method is not guaranteed to return an object whose class is java.util.Date; it could return an instance of an untrusted subclass specifically designed for malicious mischief. Such a subclass could, for example, record a reference to each instance in a private static list at the time of its creation and allow the attacker access to this list. This would give the attacker free reign over all instances. To prevent this sort of attack, do not use the clone method to make a defensive copy of a parameter whose type is subclassable by untrusted parties.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRalphView Question on Stackoverflow
Solution 1 - JavaJon SkeetView Answer on Stackoverflow
Solution 2 - JavaAmir AfghaniView Answer on Stackoverflow
Solution 3 - JavarobpvnView Answer on Stackoverflow