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>
* 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);
}
/**
* 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
* time zone and locale.
@ -445,29 +455,58 @@ public abstract class Calendar implements Serializable, Cloneable
*/
public static synchronized Calendar getInstance(TimeZone zone, Locale locale)
{
String calendarClassName = null;
ResourceBundle rb = getBundle(locale);
calendarClassName = rb.getString("calendarClass");
if (calendarClassName != null)
Class calendarClass = (Class) cache.get(locale);
Throwable exception = null;
try
{
try
if (calendarClass == null)
{
Class calendarClass = Class.forName(calendarClassName);
if (Calendar.class.isAssignableFrom(calendarClass))
ResourceBundle rb = getBundle(locale);
String calendarClassName = rb.getString("calendarClass");
if (calendarClassName != null)
{
return (Calendar) calendarClass.getConstructor(
new Class[] { TimeZone.class, Locale.class}
).newInstance(new Object[] {zone, locale} );
calendarClass = Class.forName(calendarClassName);
if (Calendar.class.isAssignableFrom(calendarClass))
cache.put(locale, calendarClass);
}
}
catch (ClassNotFoundException ex) {}
catch (IllegalAccessException ex) {}
catch (NoSuchMethodException ex) {}
catch (InstantiationException ex) {}
catch (InvocationTargetException ex) {}
// XXX should we ignore these errors or throw an exception ?
// GregorianCalendar is by far the most common case. Optimize by
// avoiding reflection.
if (calendarClass == GregorianCalendar.class)
return new GregorianCalendar(zone, locale);
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);
}
/**