diff options
author | Bryce McKinlay <mckinlay@redhat.com> | 2004-07-10 02:38:55 +0000 |
---|---|---|
committer | Bryce McKinlay <bryce@gcc.gnu.org> | 2004-07-10 03:38:55 +0100 |
commit | 3ee7acd137ffd4df6edcff788f9a75eb1f533ffc (patch) | |
tree | a21213186246ae4988b6aedc426b713636af538b /libjava/java | |
parent | 284d6a1fc39e6c7bcfca33d3f67a69547c646207 (diff) | |
download | gcc-3ee7acd137ffd4df6edcff788f9a75eb1f533ffc.zip gcc-3ee7acd137ffd4df6edcff788f9a75eb1f533ffc.tar.gz gcc-3ee7acd137ffd4df6edcff788f9a75eb1f533ffc.tar.bz2 |
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
Diffstat (limited to 'libjava/java')
-rw-r--r-- | libjava/java/util/Calendar.java | 73 |
1 files changed, 56 insertions, 17 deletions
diff --git a/libjava/java/util/Calendar.java b/libjava/java/util/Calendar.java index e1ecf3e..b7ffb33 100644 --- a/libjava/java/util/Calendar.java +++ b/libjava/java/util/Calendar.java @@ -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}); + } + } + 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; } - return new GregorianCalendar(zone, locale); + + throw new RuntimeException("Error instantiating calendar for locale " + + locale, exception); } /** |