问题
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