aboutsummaryrefslogtreecommitdiff
path: root/libjava/java
diff options
context:
space:
mode:
authorBryce McKinlay <mckinlay@redhat.com>2004-07-10 02:38:55 +0000
committerBryce McKinlay <bryce@gcc.gnu.org>2004-07-10 03:38:55 +0100
commit3ee7acd137ffd4df6edcff788f9a75eb1f533ffc (patch)
treea21213186246ae4988b6aedc426b713636af538b /libjava/java
parent284d6a1fc39e6c7bcfca33d3f67a69547c646207 (diff)
downloadgcc-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.java73
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);
}
/**