rt/emul/compact/src/main/java/java/text/DecimalFormatSymbols.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 04 Oct 2013 11:07:00 +0200
changeset 1339 8cc04f85a683
parent 1334 588d5bf7a560
permissions -rw-r--r--
Commenting out stuff in java.text so the classes compile
     1 /*
     2  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 /*
    27  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
    28  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
    29  *
    30  *   The original version of this source code and documentation is copyrighted
    31  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
    32  * materials are provided under terms of a License Agreement between Taligent
    33  * and Sun. This technology is protected by multiple US and International
    34  * patents. This notice and attribution to Taligent may not be removed.
    35  *   Taligent is a registered trademark of Taligent, Inc.
    36  *
    37  */
    38 
    39 package java.text;
    40 
    41 import java.io.IOException;
    42 import java.io.ObjectInputStream;
    43 import java.io.Serializable;
    44 import java.util.Currency;
    45 import java.util.Locale;
    46 import java.util.ResourceBundle;
    47 import java.util.concurrent.ConcurrentHashMap;
    48 
    49 /**
    50  * This class represents the set of symbols (such as the decimal separator,
    51  * the grouping separator, and so on) needed by <code>DecimalFormat</code>
    52  * to format numbers. <code>DecimalFormat</code> creates for itself an instance of
    53  * <code>DecimalFormatSymbols</code> from its locale data.  If you need to change any
    54  * of these symbols, you can get the <code>DecimalFormatSymbols</code> object from
    55  * your <code>DecimalFormat</code> and modify it.
    56  *
    57  * @see          java.util.Locale
    58  * @see          DecimalFormat
    59  * @author       Mark Davis
    60  * @author       Alan Liu
    61  */
    62 
    63 public class DecimalFormatSymbols implements Cloneable, Serializable {
    64 
    65     /**
    66      * Create a DecimalFormatSymbols object for the default locale.
    67      * This constructor can only construct instances for the locales
    68      * supported by the Java runtime environment, not for those
    69      * supported by installed
    70      * {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
    71      * implementations. For full locale coverage, use the
    72      * {@link #getInstance(Locale) getInstance} method.
    73      */
    74     public DecimalFormatSymbols() {
    75         initialize( Locale.getDefault(Locale.Category.FORMAT) );
    76     }
    77 
    78     /**
    79      * Create a DecimalFormatSymbols object for the given locale.
    80      * This constructor can only construct instances for the locales
    81      * supported by the Java runtime environment, not for those
    82      * supported by installed
    83      * {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
    84      * implementations. For full locale coverage, use the
    85      * {@link #getInstance(Locale) getInstance} method.
    86      *
    87      * @exception NullPointerException if <code>locale</code> is null
    88      */
    89     public DecimalFormatSymbols( Locale locale ) {
    90         initialize( locale );
    91     }
    92 
    93     /**
    94      * Returns an array of all locales for which the
    95      * <code>getInstance</code> methods of this class can return
    96      * localized instances.
    97      * The returned array represents the union of locales supported by the Java
    98      * runtime and by installed
    99      * {@link java.text.spi.DecimalFormatSymbolsProvider DecimalFormatSymbolsProvider}
   100      * implementations.  It must contain at least a <code>Locale</code>
   101      * instance equal to {@link java.util.Locale#US Locale.US}.
   102      *
   103      * @return An array of locales for which localized
   104      *         <code>DecimalFormatSymbols</code> instances are available.
   105      * @since 1.6
   106      */
   107     public static Locale[] getAvailableLocales() {
   108         return new Locale[] { Locale.US };
   109 //        LocaleServiceProviderPool pool =
   110 //            LocaleServiceProviderPool.getPool(DecimalFormatSymbolsProvider.class);
   111 //        return pool.getAvailableLocales();
   112     }
   113 
   114     /**
   115      * Gets the <code>DecimalFormatSymbols</code> instance for the default
   116      * locale.  This method provides access to <code>DecimalFormatSymbols</code>
   117      * instances for locales supported by the Java runtime itself as well
   118      * as for those supported by installed
   119      * {@link java.text.spi.DecimalFormatSymbolsProvider
   120      * DecimalFormatSymbolsProvider} implementations.
   121      * @return a <code>DecimalFormatSymbols</code> instance.
   122      * @since 1.6
   123      */
   124     public static final DecimalFormatSymbols getInstance() {
   125         return getInstance(Locale.getDefault(Locale.Category.FORMAT));
   126     }
   127 
   128     /**
   129      * Gets the <code>DecimalFormatSymbols</code> instance for the specified
   130      * locale.  This method provides access to <code>DecimalFormatSymbols</code>
   131      * instances for locales supported by the Java runtime itself as well
   132      * as for those supported by installed
   133      * {@link java.text.spi.DecimalFormatSymbolsProvider
   134      * DecimalFormatSymbolsProvider} implementations.
   135      * @param locale the desired locale.
   136      * @return a <code>DecimalFormatSymbols</code> instance.
   137      * @exception NullPointerException if <code>locale</code> is null
   138      * @since 1.6
   139      */
   140     public static final DecimalFormatSymbols getInstance(Locale locale) {
   141 /*
   142         // Check whether a provider can provide an implementation that's closer
   143         // to the requested locale than what the Java runtime itself can provide.
   144         LocaleServiceProviderPool pool =
   145             LocaleServiceProviderPool.getPool(DecimalFormatSymbolsProvider.class);
   146         if (pool.hasProviders()) {
   147             DecimalFormatSymbols providersInstance = pool.getLocalizedObject(
   148                                 DecimalFormatSymbolsGetter.INSTANCE, locale);
   149             if (providersInstance != null) {
   150                 return providersInstance;
   151             }
   152         }
   153 */
   154         return new DecimalFormatSymbols(locale);
   155     }
   156 
   157     /**
   158      * Gets the character used for zero. Different for Arabic, etc.
   159      */
   160     public char getZeroDigit() {
   161         return zeroDigit;
   162     }
   163 
   164     /**
   165      * Sets the character used for zero. Different for Arabic, etc.
   166      */
   167     public void setZeroDigit(char zeroDigit) {
   168         this.zeroDigit = zeroDigit;
   169     }
   170 
   171     /**
   172      * Gets the character used for thousands separator. Different for French, etc.
   173      */
   174     public char getGroupingSeparator() {
   175         return groupingSeparator;
   176     }
   177 
   178     /**
   179      * Sets the character used for thousands separator. Different for French, etc.
   180      */
   181     public void setGroupingSeparator(char groupingSeparator) {
   182         this.groupingSeparator = groupingSeparator;
   183     }
   184 
   185     /**
   186      * Gets the character used for decimal sign. Different for French, etc.
   187      */
   188     public char getDecimalSeparator() {
   189         return decimalSeparator;
   190     }
   191 
   192     /**
   193      * Sets the character used for decimal sign. Different for French, etc.
   194      */
   195     public void setDecimalSeparator(char decimalSeparator) {
   196         this.decimalSeparator = decimalSeparator;
   197     }
   198 
   199     /**
   200      * Gets the character used for per mille sign. Different for Arabic, etc.
   201      */
   202     public char getPerMill() {
   203         return perMill;
   204     }
   205 
   206     /**
   207      * Sets the character used for per mille sign. Different for Arabic, etc.
   208      */
   209     public void setPerMill(char perMill) {
   210         this.perMill = perMill;
   211     }
   212 
   213     /**
   214      * Gets the character used for percent sign. Different for Arabic, etc.
   215      */
   216     public char getPercent() {
   217         return percent;
   218     }
   219 
   220     /**
   221      * Sets the character used for percent sign. Different for Arabic, etc.
   222      */
   223     public void setPercent(char percent) {
   224         this.percent = percent;
   225     }
   226 
   227     /**
   228      * Gets the character used for a digit in a pattern.
   229      */
   230     public char getDigit() {
   231         return digit;
   232     }
   233 
   234     /**
   235      * Sets the character used for a digit in a pattern.
   236      */
   237     public void setDigit(char digit) {
   238         this.digit = digit;
   239     }
   240 
   241     /**
   242      * Gets the character used to separate positive and negative subpatterns
   243      * in a pattern.
   244      */
   245     public char getPatternSeparator() {
   246         return patternSeparator;
   247     }
   248 
   249     /**
   250      * Sets the character used to separate positive and negative subpatterns
   251      * in a pattern.
   252      */
   253     public void setPatternSeparator(char patternSeparator) {
   254         this.patternSeparator = patternSeparator;
   255     }
   256 
   257     /**
   258      * Gets the string used to represent infinity. Almost always left
   259      * unchanged.
   260      */
   261     public String getInfinity() {
   262         return infinity;
   263     }
   264 
   265     /**
   266      * Sets the string used to represent infinity. Almost always left
   267      * unchanged.
   268      */
   269     public void setInfinity(String infinity) {
   270         this.infinity = infinity;
   271     }
   272 
   273     /**
   274      * Gets the string used to represent "not a number". Almost always left
   275      * unchanged.
   276      */
   277     public String getNaN() {
   278         return NaN;
   279     }
   280 
   281     /**
   282      * Sets the string used to represent "not a number". Almost always left
   283      * unchanged.
   284      */
   285     public void setNaN(String NaN) {
   286         this.NaN = NaN;
   287     }
   288 
   289     /**
   290      * Gets the character used to represent minus sign. If no explicit
   291      * negative format is specified, one is formed by prefixing
   292      * minusSign to the positive format.
   293      */
   294     public char getMinusSign() {
   295         return minusSign;
   296     }
   297 
   298     /**
   299      * Sets the character used to represent minus sign. If no explicit
   300      * negative format is specified, one is formed by prefixing
   301      * minusSign to the positive format.
   302      */
   303     public void setMinusSign(char minusSign) {
   304         this.minusSign = minusSign;
   305     }
   306 
   307     /**
   308      * Returns the currency symbol for the currency of these
   309      * DecimalFormatSymbols in their locale.
   310      * @since 1.2
   311      */
   312     public String getCurrencySymbol()
   313     {
   314         return currencySymbol;
   315     }
   316 
   317     /**
   318      * Sets the currency symbol for the currency of these
   319      * DecimalFormatSymbols in their locale.
   320      * @since 1.2
   321      */
   322     public void setCurrencySymbol(String currency)
   323     {
   324         currencySymbol = currency;
   325     }
   326 
   327     /**
   328      * Returns the ISO 4217 currency code of the currency of these
   329      * DecimalFormatSymbols.
   330      * @since 1.2
   331      */
   332     public String getInternationalCurrencySymbol()
   333     {
   334         return intlCurrencySymbol;
   335     }
   336 
   337     /**
   338      * Sets the ISO 4217 currency code of the currency of these
   339      * DecimalFormatSymbols.
   340      * If the currency code is valid (as defined by
   341      * {@link java.util.Currency#getInstance(java.lang.String) Currency.getInstance}),
   342      * this also sets the currency attribute to the corresponding Currency
   343      * instance and the currency symbol attribute to the currency's symbol
   344      * in the DecimalFormatSymbols' locale. If the currency code is not valid,
   345      * then the currency attribute is set to null and the currency symbol
   346      * attribute is not modified.
   347      *
   348      * @see #setCurrency
   349      * @see #setCurrencySymbol
   350      * @since 1.2
   351      */
   352     public void setInternationalCurrencySymbol(String currencyCode)
   353     {
   354         intlCurrencySymbol = currencyCode;
   355         currency = null;
   356         if (currencyCode != null) {
   357             try {
   358                 currency = Currency.getInstance(currencyCode);
   359                 currencySymbol = currency.getSymbol();
   360             } catch (IllegalArgumentException e) {
   361             }
   362         }
   363     }
   364 
   365     /**
   366      * Gets the currency of these DecimalFormatSymbols. May be null if the
   367      * currency symbol attribute was previously set to a value that's not
   368      * a valid ISO 4217 currency code.
   369      *
   370      * @return the currency used, or null
   371      * @since 1.4
   372      */
   373     public Currency getCurrency() {
   374         return currency;
   375     }
   376 
   377     /**
   378      * Sets the currency of these DecimalFormatSymbols.
   379      * This also sets the currency symbol attribute to the currency's symbol
   380      * in the DecimalFormatSymbols' locale, and the international currency
   381      * symbol attribute to the currency's ISO 4217 currency code.
   382      *
   383      * @param currency the new currency to be used
   384      * @exception NullPointerException if <code>currency</code> is null
   385      * @since 1.4
   386      * @see #setCurrencySymbol
   387      * @see #setInternationalCurrencySymbol
   388      */
   389     public void setCurrency(Currency currency) {
   390         if (currency == null) {
   391             throw new NullPointerException();
   392         }
   393         this.currency = currency;
   394         intlCurrencySymbol = currency.getCurrencyCode();
   395         currencySymbol = currency.getSymbol(locale);
   396     }
   397 
   398 
   399     /**
   400      * Returns the monetary decimal separator.
   401      * @since 1.2
   402      */
   403     public char getMonetaryDecimalSeparator()
   404     {
   405         return monetarySeparator;
   406     }
   407 
   408     /**
   409      * Sets the monetary decimal separator.
   410      * @since 1.2
   411      */
   412     public void setMonetaryDecimalSeparator(char sep)
   413     {
   414         monetarySeparator = sep;
   415     }
   416 
   417     //------------------------------------------------------------
   418     // BEGIN   Package Private methods ... to be made public later
   419     //------------------------------------------------------------
   420 
   421     /**
   422      * Returns the character used to separate the mantissa from the exponent.
   423      */
   424     char getExponentialSymbol()
   425     {
   426         return exponential;
   427     }
   428   /**
   429    * Returns the string used to separate the mantissa from the exponent.
   430    * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
   431    *
   432    * @return the exponent separator string
   433    * @see #setExponentSeparator(java.lang.String)
   434    * @since 1.6
   435    */
   436     public String getExponentSeparator()
   437     {
   438         return exponentialSeparator;
   439     }
   440 
   441     /**
   442      * Sets the character used to separate the mantissa from the exponent.
   443      */
   444     void setExponentialSymbol(char exp)
   445     {
   446         exponential = exp;
   447     }
   448 
   449   /**
   450    * Sets the string used to separate the mantissa from the exponent.
   451    * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
   452    *
   453    * @param exp the exponent separator string
   454    * @exception NullPointerException if <code>exp</code> is null
   455    * @see #getExponentSeparator()
   456    * @since 1.6
   457    */
   458     public void setExponentSeparator(String exp)
   459     {
   460         if (exp == null) {
   461             throw new NullPointerException();
   462         }
   463         exponentialSeparator = exp;
   464      }
   465 
   466 
   467     //------------------------------------------------------------
   468     // END     Package Private methods ... to be made public later
   469     //------------------------------------------------------------
   470 
   471     /**
   472      * Standard override.
   473      */
   474     public Object clone() {
   475         try {
   476             return (DecimalFormatSymbols)super.clone();
   477             // other fields are bit-copied
   478         } catch (CloneNotSupportedException e) {
   479             throw new InternalError();
   480         }
   481     }
   482 
   483     /**
   484      * Override equals.
   485      */
   486     public boolean equals(Object obj) {
   487         if (obj == null) return false;
   488         if (this == obj) return true;
   489         if (getClass() != obj.getClass()) return false;
   490         DecimalFormatSymbols other = (DecimalFormatSymbols) obj;
   491         return (zeroDigit == other.zeroDigit &&
   492         groupingSeparator == other.groupingSeparator &&
   493         decimalSeparator == other.decimalSeparator &&
   494         percent == other.percent &&
   495         perMill == other.perMill &&
   496         digit == other.digit &&
   497         minusSign == other.minusSign &&
   498         patternSeparator == other.patternSeparator &&
   499         infinity.equals(other.infinity) &&
   500         NaN.equals(other.NaN) &&
   501         currencySymbol.equals(other.currencySymbol) &&
   502         intlCurrencySymbol.equals(other.intlCurrencySymbol) &&
   503         currency == other.currency &&
   504         monetarySeparator == other.monetarySeparator &&
   505         exponentialSeparator.equals(other.exponentialSeparator) &&
   506         locale.equals(other.locale));
   507     }
   508 
   509     /**
   510      * Override hashCode.
   511      */
   512     public int hashCode() {
   513             int result = zeroDigit;
   514             result = result * 37 + groupingSeparator;
   515             result = result * 37 + decimalSeparator;
   516             return result;
   517     }
   518 
   519     /**
   520      * Initializes the symbols from the FormatData resource bundle.
   521      */
   522     private void initialize( Locale locale ) {
   523         this.locale = locale;
   524 
   525         // get resource bundle data - try the cache first
   526         boolean needCacheUpdate = false;
   527         Object[] data = cachedLocaleData.get(locale);
   528         if (data == null) {  /* cache miss */
   529             // When numbering system is thai (Locale's extension contains u-nu-thai),
   530             // we read the data from th_TH_TH.
   531             Locale lookupLocale = locale;
   532             String numberType = locale.getUnicodeLocaleType("nu");
   533             if (numberType != null && numberType.equals("thai")) {
   534                 lookupLocale = new Locale("th", "TH", "TH");
   535             }
   536             data = new Object[3];
   537 //            ResourceBundle rb = LocaleData.getNumberFormatData(lookupLocale);
   538 //            data[0] = rb.getStringArray("NumberElements");
   539             needCacheUpdate = true;
   540         }
   541 
   542         String[] numberElements = (String[]) data[0];
   543 
   544         decimalSeparator = numberElements[0].charAt(0);
   545         groupingSeparator = numberElements[1].charAt(0);
   546         patternSeparator = numberElements[2].charAt(0);
   547         percent = numberElements[3].charAt(0);
   548         zeroDigit = numberElements[4].charAt(0); //different for Arabic,etc.
   549         digit = numberElements[5].charAt(0);
   550         minusSign = numberElements[6].charAt(0);
   551         exponential = numberElements[7].charAt(0);
   552         exponentialSeparator = numberElements[7]; //string representation new since 1.6
   553         perMill = numberElements[8].charAt(0);
   554         infinity  = numberElements[9];
   555         NaN = numberElements[10];
   556 
   557         // Try to obtain the currency used in the locale's country.
   558         // Check for empty country string separately because it's a valid
   559         // country ID for Locale (and used for the C locale), but not a valid
   560         // ISO 3166 country code, and exceptions are expensive.
   561         if (!"".equals(locale.getCountry())) {
   562             try {
   563                 currency = Currency.getInstance(locale);
   564             } catch (IllegalArgumentException e) {
   565                 // use default values below for compatibility
   566             }
   567         }
   568         if (currency != null) {
   569             intlCurrencySymbol = currency.getCurrencyCode();
   570             if (data[1] != null && data[1] == intlCurrencySymbol) {
   571                 currencySymbol = (String) data[2];
   572             } else {
   573                 currencySymbol = currency.getSymbol(locale);
   574                 data[1] = intlCurrencySymbol;
   575                 data[2] = currencySymbol;
   576                 needCacheUpdate = true;
   577             }
   578         } else {
   579             // default values
   580             intlCurrencySymbol = "XXX";
   581             try {
   582                 currency = Currency.getInstance(intlCurrencySymbol);
   583             } catch (IllegalArgumentException e) {
   584             }
   585             currencySymbol = "\u00A4";
   586         }
   587         // Currently the monetary decimal separator is the same as the
   588         // standard decimal separator for all locales that we support.
   589         // If that changes, add a new entry to NumberElements.
   590         monetarySeparator = decimalSeparator;
   591 
   592         if (needCacheUpdate) {
   593             cachedLocaleData.putIfAbsent(locale, data);
   594         }
   595     }
   596 
   597     /**
   598      * Reads the default serializable fields, provides default values for objects
   599      * in older serial versions, and initializes non-serializable fields.
   600      * If <code>serialVersionOnStream</code>
   601      * is less than 1, initializes <code>monetarySeparator</code> to be
   602      * the same as <code>decimalSeparator</code> and <code>exponential</code>
   603      * to be 'E'.
   604      * If <code>serialVersionOnStream</code> is less than 2,
   605      * initializes <code>locale</code>to the root locale, and initializes
   606      * If <code>serialVersionOnStream</code> is less than 3, it initializes
   607      * <code>exponentialSeparator</code> using <code>exponential</code>.
   608      * Sets <code>serialVersionOnStream</code> back to the maximum allowed value so that
   609      * default serialization will work properly if this object is streamed out again.
   610      * Initializes the currency from the intlCurrencySymbol field.
   611      *
   612      * @since JDK 1.1.6
   613      */
   614     private void readObject(ObjectInputStream stream)
   615             throws IOException, ClassNotFoundException {
   616         stream.defaultReadObject();
   617         if (serialVersionOnStream < 1) {
   618             // Didn't have monetarySeparator or exponential field;
   619             // use defaults.
   620             monetarySeparator = decimalSeparator;
   621             exponential       = 'E';
   622         }
   623         if (serialVersionOnStream < 2) {
   624             // didn't have locale; use root locale
   625             locale = Locale.ROOT;
   626         }
   627         if (serialVersionOnStream < 3) {
   628             // didn't have exponentialSeparator. Create one using exponential
   629             exponentialSeparator = Character.toString(exponential);
   630         }
   631         serialVersionOnStream = currentSerialVersion;
   632 
   633         if (intlCurrencySymbol != null) {
   634             try {
   635                  currency = Currency.getInstance(intlCurrencySymbol);
   636             } catch (IllegalArgumentException e) {
   637             }
   638         }
   639     }
   640 
   641     /**
   642      * Character used for zero.
   643      *
   644      * @serial
   645      * @see #getZeroDigit
   646      */
   647     private  char    zeroDigit;
   648 
   649     /**
   650      * Character used for thousands separator.
   651      *
   652      * @serial
   653      * @see #getGroupingSeparator
   654      */
   655     private  char    groupingSeparator;
   656 
   657     /**
   658      * Character used for decimal sign.
   659      *
   660      * @serial
   661      * @see #getDecimalSeparator
   662      */
   663     private  char    decimalSeparator;
   664 
   665     /**
   666      * Character used for per mille sign.
   667      *
   668      * @serial
   669      * @see #getPerMill
   670      */
   671     private  char    perMill;
   672 
   673     /**
   674      * Character used for percent sign.
   675      * @serial
   676      * @see #getPercent
   677      */
   678     private  char    percent;
   679 
   680     /**
   681      * Character used for a digit in a pattern.
   682      *
   683      * @serial
   684      * @see #getDigit
   685      */
   686     private  char    digit;
   687 
   688     /**
   689      * Character used to separate positive and negative subpatterns
   690      * in a pattern.
   691      *
   692      * @serial
   693      * @see #getPatternSeparator
   694      */
   695     private  char    patternSeparator;
   696 
   697     /**
   698      * String used to represent infinity.
   699      * @serial
   700      * @see #getInfinity
   701      */
   702     private  String  infinity;
   703 
   704     /**
   705      * String used to represent "not a number".
   706      * @serial
   707      * @see #getNaN
   708      */
   709     private  String  NaN;
   710 
   711     /**
   712      * Character used to represent minus sign.
   713      * @serial
   714      * @see #getMinusSign
   715      */
   716     private  char    minusSign;
   717 
   718     /**
   719      * String denoting the local currency, e.g. "$".
   720      * @serial
   721      * @see #getCurrencySymbol
   722      */
   723     private  String  currencySymbol;
   724 
   725     /**
   726      * ISO 4217 currency code denoting the local currency, e.g. "USD".
   727      * @serial
   728      * @see #getInternationalCurrencySymbol
   729      */
   730     private  String  intlCurrencySymbol;
   731 
   732     /**
   733      * The decimal separator used when formatting currency values.
   734      * @serial
   735      * @since JDK 1.1.6
   736      * @see #getMonetaryDecimalSeparator
   737      */
   738     private  char    monetarySeparator; // Field new in JDK 1.1.6
   739 
   740     /**
   741      * The character used to distinguish the exponent in a number formatted
   742      * in exponential notation, e.g. 'E' for a number such as "1.23E45".
   743      * <p>
   744      * Note that the public API provides no way to set this field,
   745      * even though it is supported by the implementation and the stream format.
   746      * The intent is that this will be added to the API in the future.
   747      *
   748      * @serial
   749      * @since JDK 1.1.6
   750      */
   751     private  char    exponential;       // Field new in JDK 1.1.6
   752 
   753   /**
   754    * The string used to separate the mantissa from the exponent.
   755    * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
   756    * <p>
   757    * If both <code>exponential</code> and <code>exponentialSeparator</code>
   758    * exist, this <code>exponentialSeparator</code> has the precedence.
   759    *
   760    * @serial
   761    * @since 1.6
   762    */
   763     private  String    exponentialSeparator;       // Field new in JDK 1.6
   764 
   765     /**
   766      * The locale of these currency format symbols.
   767      *
   768      * @serial
   769      * @since 1.4
   770      */
   771     private Locale locale;
   772 
   773     // currency; only the ISO code is serialized.
   774     private transient Currency currency;
   775 
   776     // Proclaim JDK 1.1 FCS compatibility
   777     static final long serialVersionUID = 5772796243397350300L;
   778 
   779     // The internal serial version which says which version was written
   780     // - 0 (default) for version up to JDK 1.1.5
   781     // - 1 for version from JDK 1.1.6, which includes two new fields:
   782     //     monetarySeparator and exponential.
   783     // - 2 for version from J2SE 1.4, which includes locale field.
   784     // - 3 for version from J2SE 1.6, which includes exponentialSeparator field.
   785     private static final int currentSerialVersion = 3;
   786 
   787     /**
   788      * Describes the version of <code>DecimalFormatSymbols</code> present on the stream.
   789      * Possible values are:
   790      * <ul>
   791      * <li><b>0</b> (or uninitialized): versions prior to JDK 1.1.6.
   792      *
   793      * <li><b>1</b>: Versions written by JDK 1.1.6 or later, which include
   794      *      two new fields: <code>monetarySeparator</code> and <code>exponential</code>.
   795      * <li><b>2</b>: Versions written by J2SE 1.4 or later, which include a
   796      *      new <code>locale</code> field.
   797      * <li><b>3</b>: Versions written by J2SE 1.6 or later, which include a
   798      *      new <code>exponentialSeparator</code> field.
   799      * </ul>
   800      * When streaming out a <code>DecimalFormatSymbols</code>, the most recent format
   801      * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
   802      * is always written.
   803      *
   804      * @serial
   805      * @since JDK 1.1.6
   806      */
   807     private int serialVersionOnStream = currentSerialVersion;
   808 
   809     /**
   810      * cache to hold the NumberElements and the Currency
   811      * of a Locale.
   812      */
   813     private static final ConcurrentHashMap<Locale, Object[]> cachedLocaleData = new ConcurrentHashMap<Locale, Object[]>(3);
   814 
   815     /**
   816      * Obtains a DecimalFormatSymbols instance from a DecimalFormatSymbolsProvider
   817      * implementation.
   818     private static class DecimalFormatSymbolsGetter
   819         implements LocaleServiceProviderPool.LocalizedObjectGetter<DecimalFormatSymbolsProvider,
   820                                                                    DecimalFormatSymbols> {
   821         private static final DecimalFormatSymbolsGetter INSTANCE =
   822             new DecimalFormatSymbolsGetter();
   823 
   824         public DecimalFormatSymbols getObject(
   825                                 DecimalFormatSymbolsProvider decimalFormatSymbolsProvider,
   826                                 Locale locale,
   827                                 String key,
   828                                 Object... params) {
   829             assert params.length == 0;
   830             return decimalFormatSymbolsProvider.getInstance(locale);
   831         }
   832     }
   833      */
   834 }