java.util.Calendar.java (cache): New private static field.

2004-07-09  Bryce McKinlay  <mckinlay@redhat.com>

	* java.util.Calendar.java (cache): New private static field. Cached
	mappings of locales->calendar classes.
	(ctorArgTypes): New private static field. Singleton argument for
	calendar class constructor lookup.
	(getInstance): Cache Locale->Calendar class mappings using HashMap.
	Optimize by bypassing reflection instantiation for the
	GregorianCalendar case.

From-SVN: r84438
This commit is contained in:
Bryce McKinlay 2004-07-10 02:38:55 +00:00 committed by Bryce McKinlay
parent 284d6a1fc3
commit 3ee7acd137
2 changed files with 66 additions and 17 deletions

View file

@ -1,3 +1,13 @@
2004-07-09 Bryce McKinlay <mckinlay@redhat.com>
* java.util.Calendar.java (cache): New private static field. Cached
mappings of locales->calendar classes.
(ctorArgTypes): New private static field. Singleton argument for
calendar class constructor lookup.
(getInstance): Cache Locale->Calendar class mappings using HashMap.
Optimize by bypassing reflection instantiation for the
GregorianCalendar case.
2004-07-09 Bryce McKinlay <mckinlay@redhat.com> 2004-07-09 Bryce McKinlay <mckinlay@redhat.com>
* java/util/Calendar.java: Use getSystemClassLoader as argument for * java/util/Calendar.java: Use getSystemClassLoader as argument for

View file

@ -437,6 +437,16 @@ public abstract class Calendar implements Serializable, Cloneable
return getInstance(TimeZone.getDefault(), locale); return getInstance(TimeZone.getDefault(), locale);
} }
/**
* Cache of locale->calendar-class mappings. This avoids having to do a ResourceBundle
* lookup for every getInstance call.
*/
private static HashMap cache = new HashMap();
/** Preset argument types for calendar-class constructor lookup. */
private static Class[] ctorArgTypes
= new Class[] {TimeZone.class, Locale.class};
/** /**
* Creates a calendar representing the actual time, using the given * Creates a calendar representing the actual time, using the given
* time zone and locale. * time zone and locale.
@ -445,29 +455,58 @@ public abstract class Calendar implements Serializable, Cloneable
*/ */
public static synchronized Calendar getInstance(TimeZone zone, Locale locale) public static synchronized Calendar getInstance(TimeZone zone, Locale locale)
{ {
String calendarClassName = null; Class calendarClass = (Class) cache.get(locale);
ResourceBundle rb = getBundle(locale); Throwable exception = null;
calendarClassName = rb.getString("calendarClass");
if (calendarClassName != null) try
{ {
try if (calendarClass == null)
{ {
Class calendarClass = Class.forName(calendarClassName); ResourceBundle rb = getBundle(locale);
if (Calendar.class.isAssignableFrom(calendarClass)) String calendarClassName = rb.getString("calendarClass");
if (calendarClassName != null)
{ {
return (Calendar) calendarClass.getConstructor( calendarClass = Class.forName(calendarClassName);
new Class[] { TimeZone.class, Locale.class} if (Calendar.class.isAssignableFrom(calendarClass))
).newInstance(new Object[] {zone, locale} ); cache.put(locale, calendarClass);
} }
} }
catch (ClassNotFoundException ex) {}
catch (IllegalAccessException ex) {} // GregorianCalendar is by far the most common case. Optimize by
catch (NoSuchMethodException ex) {} // avoiding reflection.
catch (InstantiationException ex) {} if (calendarClass == GregorianCalendar.class)
catch (InvocationTargetException ex) {} return new GregorianCalendar(zone, locale);
// XXX should we ignore these errors or throw an exception ?
if (Calendar.class.isAssignableFrom(calendarClass))
{
Constructor ctor = calendarClass.getConstructor(ctorArgTypes);
return (Calendar) ctor.newInstance(new Object[] {zone, locale});
}
} }
return new GregorianCalendar(zone, locale); catch (ClassNotFoundException ex)
{
exception = ex;
}
catch (IllegalAccessException ex)
{
exception = ex;
}
catch (NoSuchMethodException ex)
{
exception = ex;
}
catch (InstantiationException ex)
{
exception = ex;
}
catch (InvocationTargetException ex)
{
exception = ex;
}
throw new RuntimeException("Error instantiating calendar for locale " +
locale, exception);
} }
/** /**