Duplicate :
|
|
Duplicate :
|
|
Relates :
|
|
Relates :
|
Name: bb33257 Date: 02/05/99 There is a problem in Calendar in JDK 1.2. Subclasses that were written for JDK 1.1 don't work anymore. Consider a subclass that has to work with both 1.1.x and 1.2. It can't use the stamp array in my computeTime method. Instead, it has to rely on calling isSet(). Consider the following calls: // Now find the # of days in the month c.roll(Calendar.DATE, false); daysInMonth = c.get(Calendar.DATE); When roll is called, it ends up calling set on the DATE field, which has the side effect of setting areFieldsSet and isTimeSet to false. It also sets isSet[DATE] to true and updates stamp[DATE]. If c is a Gregorian calendar, then it works properly. Here's what happens: 1. The roll method calls complete, which calls computeFields. 2. After the fields values are set, GregorianCalendar.computeFields sets each element in the stamp array to INTERNALLY_SET. 3. The get method immediately calls complete, which notices that isTimeSet is false and calls updateTime, which in turn calls computeTime. 4. That method uses the stamp array to decide which fields it should use to compute the time. It doesn't look at the isSet array at all. It properly updates the time based on the relevant fields. 5. Next, complete calls computeFields. 6. Finally, get returns fields[DATE]. In contrast, if c is a JDK 1.1-compatible subclass, this is what happens: 1. same thing: roll ends up calling computeFields. 2. Nothing (!): computeFields method doesn't have access to the stamp array. 3. same thing: get ends up calling computeTime. 4. computeTime method calls isSet() to decide which combination of fields to use, much like the Gregorian calendar used to do. 5. In 1.2, isSet() returns (stamp[field] != UNSET). This is almost always false, because computeFields wasn't able to update the stamp array. 6. The calendar thinks there aren't enough fields set to compute the time, so it throws an exception. Boom. To restate the requirements for 1.2 and later, we want the following: 1. Subclasses under 1.1 should work under 1.2. This means isSet() must work, in particular, it must read the isSet[] array, since subclasses may modify that array directly. 2. Subclasses under 1.2 should work. If a subclass sets up the fields, it must be able to make isSet() do the right thing. 3. GregorianCalendar and other subclasses within java.text must work. For this to be true, isSet() has to read the time stamp. So I propose: 1. Make isSet() read the isSet[] array. 2. Make Calendar.isSet() non-final, and for GregorianCalendar, override it to read the time stamp. (Review ID: 53793) ======================================================================
|