3

Netbeans is complaining about this code, which appears on the IDEA Code Inspections List.

 public Date getStartDate()
 {
    return theStartDate;
 }

IDEA site says:

This inspection reports any attempt to return a java.lang.Date or java.lang.Calendar field from a method. Since Date or Calendar are often treated as immutable values but are actually mutable, this construct may result in an object having its state modified unexpectedly. While occasionally useful for performance reasons, this construct is inherently bug-prone.

How else would I return a Date?

5 Answers5

9

You should most likely return a copy of the value in question, rather than your current object, to avoid unintentional modifications

the simplest is probably
return new Date(theStartDate.getTime());

This is because java.util.Date is a mutable object, and you want to avoid problems from your caller mistakenly or maliciously doing something like:

yourObject.getStartDate().setTime(0);

If you make the change above, a statement like the one above becomes harmless.

Why a copy constructor and not the clone mehod? See here: java.util.Date clone or copy to not expose internal reference

Note that this will have the performance penalty of creating a new object on every call to the method, so use with caution.

Community
  • 1
  • 1
JohnnyO
  • 3,018
  • 18
  • 30
2

return new Date(theStartDate.getTime());

2

IDEA is simply saying that Date objects are often used as immutable objects. The reasonable solution is to return a new Date object, with theStartDate.getTime() in it's constructor. This maintains the immutability of the original Date object :)

christopher
  • 26,815
  • 5
  • 55
  • 89
1

You could return the date as an immutable long (Date.getTime()) . This insures that the date is not changed by the caller.

Another option would be to get the date as a long and return a new date return new Date(dateAsLong). This would protect the original date while still returning a Date object.

Rylander
  • 19,449
  • 25
  • 93
  • 144
  • A `long` for a date? Yuck. – Tom Hawtin - tackline Feb 25 '13 at 22:29
  • @TomHawtin-tackline The only non-deprecated constructor for java date (http://docs.oracle.com/javase/7/docs/api/java/sql/Date.html) takes long as the input parameter for "milliseconds since January 1, 1970, 00:00:00 GMT" – Rylander Feb 25 '13 at 22:40
  • So call it for me. (Point of pedantry: The no-args constructor is also non-deprecated.) – Tom Hawtin - tackline Feb 25 '13 at 22:46
  • @TomHawtin-tackline I was looking at the wrong date (sql.date vs util.date http://docs.oracle.com/javase/7/docs/api/java/util/Date.html) Long is a valid way to represent time but if used people should be aware that it does not have the protections or context that a date object would. – Rylander Feb 25 '13 at 23:01
1

Perhaps you could return the long milliseconds value that the Date represents:

public long getStartDateMilliseconds()
{
    return theStartDate.getTime();
}

Returning the long value still allows you to return the Date information, and prevents the caller from modifying a returned Date. Then the caller could re-construct the Date:

Date theDate = new Date(myObject.getStartDateMilliseconds());

That should pass the IntelliJ inspection.

rgettman
  • 176,041
  • 30
  • 275
  • 357