问题
I have a class with a method I'm passing in several Calendar objects. Within that method I'm adding several days/months to the Calendar objects.
However, on return of the method, the Calendar objects passed in no longer hold the updated dates from the method that did the 'processing'.
I'd have thought with Calendar objects, changes would be maintained regardless of where id changed state? Code below:
Calendar aDate = Calendar.getInstance();
aDate.set(2016, 2, 30);
Calendar start = Calendar.getInstance();
myClass.setStartAndEnd(aDate, start);
Then the setStartAndEnd method...
void setStartAndEnd(Calendar aDate, Calendar start) {
if (aDate.get(Calendar.DAY_OF_WEEK) == 1) {
start = aDate;
} else {
start.add(Calendar.DAY_OF_WEEK, 5);
}
}
In this case I'd expect 'start' to end up with 5 days added to March 30th, however on return of the method it still ends up as March 30th
回答1:
You do two different things:
if (aDate.get(Calendar.DAY_OF_WEEK) == 1) {
start = aDate;
--by this, your reassign local start
reference to aDate
, so local start
from now points not to start
passed as an argument, but to aDate
. Out of the method, start
is not reassigned because reference to it was passed by value;
} else {
start.add(Calendar.DAY_OF_WEEK, 5);
--by this, you modify local start
, which still points to start
passed as argument, so all changes are reflected in the object out of the method also.
To get rid of situations when arguments are reassigned by mistake, make them final
:
void setStartAndEnd(final Calendar aDate, final Calendar start) {
// ...
}
回答2:
As @fge noted, the Calendar object is mutable. Therefore, when the start
object is passed to setStartAndEnd
, method, it is possible to modify the object through methods such as start.add()
. There are two ways, therefore, to potentially fix the code.
Option 1. In setStartAndEnd
do not set the start
variable (which is local) to end, but use methods to adjust its value.
void setStartAndEnd(Calendar aDate, Calendar start) {
if (aDate.get(Calendar.DAY_OF_WEEK) == 1) {
start.setTime(aDate.getTime());
} else {
start.add(Calendar.DAY_OF_WEEK, 5);
}
}
Option 2. change the method to return a Calendar object and return a new Calendar object with the correct value.
来源:https://stackoverflow.com/questions/36336774/java-calendar-pass-by-reference