src/java.base/share/classes/java/text/NumberFormat.java
changeset 47216 71c04702a3d5
parent 47020 2c55106dc37b
child 48026 89deac44e515
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 1996, 2017, 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.InvalidObjectException;
       
    42 import java.io.IOException;
       
    43 import java.io.ObjectInputStream;
       
    44 import java.io.ObjectOutputStream;
       
    45 import java.math.BigInteger;
       
    46 import java.math.RoundingMode;
       
    47 import java.text.spi.NumberFormatProvider;
       
    48 import java.util.Currency;
       
    49 import java.util.HashMap;
       
    50 import java.util.Hashtable;
       
    51 import java.util.Locale;
       
    52 import java.util.Map;
       
    53 import java.util.ResourceBundle;
       
    54 import java.util.concurrent.atomic.AtomicInteger;
       
    55 import java.util.concurrent.atomic.AtomicLong;
       
    56 import java.util.spi.LocaleServiceProvider;
       
    57 import sun.util.locale.provider.LocaleProviderAdapter;
       
    58 import sun.util.locale.provider.LocaleServiceProviderPool;
       
    59 
       
    60 /**
       
    61  * <code>NumberFormat</code> is the abstract base class for all number
       
    62  * formats. This class provides the interface for formatting and parsing
       
    63  * numbers. <code>NumberFormat</code> also provides methods for determining
       
    64  * which locales have number formats, and what their names are.
       
    65  *
       
    66  * <p>
       
    67  * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
       
    68  * Your code can be completely independent of the locale conventions for
       
    69  * decimal points, thousands-separators, or even the particular decimal
       
    70  * digits used, or whether the number format is even decimal.
       
    71  *
       
    72  * <p>
       
    73  * To format a number for the current Locale, use one of the factory
       
    74  * class methods:
       
    75  * <blockquote>
       
    76  * <pre>{@code
       
    77  * myString = NumberFormat.getInstance().format(myNumber);
       
    78  * }</pre>
       
    79  * </blockquote>
       
    80  * If you are formatting multiple numbers, it is
       
    81  * more efficient to get the format and use it multiple times so that
       
    82  * the system doesn't have to fetch the information about the local
       
    83  * language and country conventions multiple times.
       
    84  * <blockquote>
       
    85  * <pre>{@code
       
    86  * NumberFormat nf = NumberFormat.getInstance();
       
    87  * for (int i = 0; i < myNumber.length; ++i) {
       
    88  *     output.println(nf.format(myNumber[i]) + "; ");
       
    89  * }
       
    90  * }</pre>
       
    91  * </blockquote>
       
    92  * To format a number for a different Locale, specify it in the
       
    93  * call to <code>getInstance</code>.
       
    94  * <blockquote>
       
    95  * <pre>{@code
       
    96  * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
       
    97  * }</pre>
       
    98  * </blockquote>
       
    99  * You can also use a <code>NumberFormat</code> to parse numbers:
       
   100  * <blockquote>
       
   101  * <pre>{@code
       
   102  * myNumber = nf.parse(myString);
       
   103  * }</pre>
       
   104  * </blockquote>
       
   105  * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
       
   106  * normal number format. Use <code>getIntegerInstance</code> to get an
       
   107  * integer number format. Use <code>getCurrencyInstance</code> to get the
       
   108  * currency number format. And use <code>getPercentInstance</code> to get a
       
   109  * format for displaying percentages. With this format, a fraction like
       
   110  * 0.53 is displayed as 53%.
       
   111  *
       
   112  * <p>
       
   113  * You can also control the display of numbers with such methods as
       
   114  * <code>setMinimumFractionDigits</code>.
       
   115  * If you want even more control over the format or parsing,
       
   116  * or want to give your users more control,
       
   117  * you can try casting the <code>NumberFormat</code> you get from the factory methods
       
   118  * to a <code>DecimalFormat</code>. This will work for the vast majority
       
   119  * of locales; just remember to put it in a <code>try</code> block in case you
       
   120  * encounter an unusual one.
       
   121  *
       
   122  * <p>
       
   123  * NumberFormat and DecimalFormat are designed such that some controls
       
   124  * work for formatting and others work for parsing.  The following is
       
   125  * the detailed description for each these control methods,
       
   126  * <p>
       
   127  * setParseIntegerOnly : only affects parsing, e.g.
       
   128  * if true,  "3456.78" &rarr; 3456 (and leaves the parse position just after index 6)
       
   129  * if false, "3456.78" &rarr; 3456.78 (and leaves the parse position just after index 8)
       
   130  * This is independent of formatting.  If you want to not show a decimal point
       
   131  * where there might be no digits after the decimal point, use
       
   132  * setDecimalSeparatorAlwaysShown.
       
   133  * <p>
       
   134  * setDecimalSeparatorAlwaysShown : only affects formatting, and only where
       
   135  * there might be no digits after the decimal point, such as with a pattern
       
   136  * like "#,##0.##", e.g.,
       
   137  * if true,  3456.00 &rarr; "3,456."
       
   138  * if false, 3456.00 &rarr; "3456"
       
   139  * This is independent of parsing.  If you want parsing to stop at the decimal
       
   140  * point, use setParseIntegerOnly.
       
   141  *
       
   142  * <p>
       
   143  * You can also use forms of the <code>parse</code> and <code>format</code>
       
   144  * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
       
   145  * allow you to:
       
   146  * <ul>
       
   147  * <li> progressively parse through pieces of a string
       
   148  * <li> align the decimal point and other areas
       
   149  * </ul>
       
   150  * For example, you can align numbers in two ways:
       
   151  * <ol>
       
   152  * <li> If you are using a monospaced font with spacing for alignment,
       
   153  *      you can pass the <code>FieldPosition</code> in your format call, with
       
   154  *      <code>field</code> = <code>INTEGER_FIELD</code>. On output,
       
   155  *      <code>getEndIndex</code> will be set to the offset between the
       
   156  *      last character of the integer and the decimal. Add
       
   157  *      (desiredSpaceCount - getEndIndex) spaces at the front of the string.
       
   158  *
       
   159  * <li> If you are using proportional fonts,
       
   160  *      instead of padding with spaces, measure the width
       
   161  *      of the string in pixels from the start to <code>getEndIndex</code>.
       
   162  *      Then move the pen by
       
   163  *      (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
       
   164  *      It also works where there is no decimal, but possibly additional
       
   165  *      characters at the end, e.g., with parentheses in negative
       
   166  *      numbers: "(12)" for -12.
       
   167  * </ol>
       
   168  *
       
   169  * <h3><a id="synchronization">Synchronization</a></h3>
       
   170  *
       
   171  * <p>
       
   172  * Number formats are generally not synchronized.
       
   173  * It is recommended to create separate format instances for each thread.
       
   174  * If multiple threads access a format concurrently, it must be synchronized
       
   175  * externally.
       
   176  *
       
   177  * @implSpec The {@link #format(double, StringBuffer, FieldPosition)},
       
   178  * {@link #format(long, StringBuffer, FieldPosition)} and
       
   179  * {@link #parse(String, ParsePosition)} methods may throw
       
   180  * {@code NullPointerException}, if any of their parameter is {@code null}.
       
   181  * The subclass may provide its own implementation and specification about
       
   182  * {@code NullPointerException}.
       
   183  *
       
   184  * <p>
       
   185  * The default implementation provides rounding modes defined
       
   186  * in {@link java.math.RoundingMode} for formatting numbers. It
       
   187  * uses the {@linkplain java.math.RoundingMode#HALF_EVEN
       
   188  * round half-even algorithm}. To change the rounding mode use
       
   189  * {@link #setRoundingMode(java.math.RoundingMode) setRoundingMode}.
       
   190  * The {@code NumberFormat} returned by the static factory methods is
       
   191  * configured to round floating point numbers using half-even
       
   192  * rounding (see {@link java.math.RoundingMode#HALF_EVEN
       
   193  * RoundingMode.HALF_EVEN}) for formatting.
       
   194  *
       
   195  * @see          DecimalFormat
       
   196  * @see          ChoiceFormat
       
   197  * @author       Mark Davis
       
   198  * @author       Helena Shih
       
   199  * @since 1.1
       
   200  */
       
   201 public abstract class NumberFormat extends Format  {
       
   202 
       
   203     /**
       
   204      * Field constant used to construct a FieldPosition object. Signifies that
       
   205      * the position of the integer part of a formatted number should be returned.
       
   206      * @see java.text.FieldPosition
       
   207      */
       
   208     public static final int INTEGER_FIELD = 0;
       
   209 
       
   210     /**
       
   211      * Field constant used to construct a FieldPosition object. Signifies that
       
   212      * the position of the fraction part of a formatted number should be returned.
       
   213      * @see java.text.FieldPosition
       
   214      */
       
   215     public static final int FRACTION_FIELD = 1;
       
   216 
       
   217     /**
       
   218      * Sole constructor.  (For invocation by subclass constructors, typically
       
   219      * implicit.)
       
   220      */
       
   221     protected NumberFormat() {
       
   222     }
       
   223 
       
   224     /**
       
   225      * Formats a number and appends the resulting text to the given string
       
   226      * buffer.
       
   227      * The number can be of any subclass of {@link java.lang.Number}.
       
   228      * <p>
       
   229      * This implementation extracts the number's value using
       
   230      * {@link java.lang.Number#longValue()} for all integral type values that
       
   231      * can be converted to <code>long</code> without loss of information,
       
   232      * including <code>BigInteger</code> values with a
       
   233      * {@link java.math.BigInteger#bitLength() bit length} of less than 64,
       
   234      * and {@link java.lang.Number#doubleValue()} for all other types. It
       
   235      * then calls
       
   236      * {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)}
       
   237      * or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}.
       
   238      * This may result in loss of magnitude information and precision for
       
   239      * <code>BigInteger</code> and <code>BigDecimal</code> values.
       
   240      * @param number     the number to format
       
   241      * @param toAppendTo the <code>StringBuffer</code> to which the formatted
       
   242      *                   text is to be appended
       
   243      * @param pos        On input: an alignment field, if desired.
       
   244      *                   On output: the offsets of the alignment field.
       
   245      * @return           the value passed in as <code>toAppendTo</code>
       
   246      * @exception        IllegalArgumentException if <code>number</code> is
       
   247      *                   null or not an instance of <code>Number</code>.
       
   248      * @exception        NullPointerException if <code>toAppendTo</code> or
       
   249      *                   <code>pos</code> is null
       
   250      * @exception        ArithmeticException if rounding is needed with rounding
       
   251      *                   mode being set to RoundingMode.UNNECESSARY
       
   252      * @see              java.text.FieldPosition
       
   253      */
       
   254     @Override
       
   255     public StringBuffer format(Object number,
       
   256                                StringBuffer toAppendTo,
       
   257                                FieldPosition pos) {
       
   258         if (number instanceof Long || number instanceof Integer ||
       
   259             number instanceof Short || number instanceof Byte ||
       
   260             number instanceof AtomicInteger || number instanceof AtomicLong ||
       
   261             (number instanceof BigInteger &&
       
   262              ((BigInteger)number).bitLength() < 64)) {
       
   263             return format(((Number)number).longValue(), toAppendTo, pos);
       
   264         } else if (number instanceof Number) {
       
   265             return format(((Number)number).doubleValue(), toAppendTo, pos);
       
   266         } else {
       
   267             throw new IllegalArgumentException("Cannot format given Object as a Number");
       
   268         }
       
   269     }
       
   270 
       
   271     /**
       
   272      * Parses text from a string to produce a <code>Number</code>.
       
   273      * <p>
       
   274      * The method attempts to parse text starting at the index given by
       
   275      * <code>pos</code>.
       
   276      * If parsing succeeds, then the index of <code>pos</code> is updated
       
   277      * to the index after the last character used (parsing does not necessarily
       
   278      * use all characters up to the end of the string), and the parsed
       
   279      * number is returned. The updated <code>pos</code> can be used to
       
   280      * indicate the starting point for the next call to this method.
       
   281      * If an error occurs, then the index of <code>pos</code> is not
       
   282      * changed, the error index of <code>pos</code> is set to the index of
       
   283      * the character where the error occurred, and null is returned.
       
   284      * <p>
       
   285      * See the {@link #parse(String, ParsePosition)} method for more information
       
   286      * on number parsing.
       
   287      *
       
   288      * @param source A <code>String</code>, part of which should be parsed.
       
   289      * @param pos A <code>ParsePosition</code> object with index and error
       
   290      *            index information as described above.
       
   291      * @return A <code>Number</code> parsed from the string. In case of
       
   292      *         error, returns null.
       
   293      * @throws NullPointerException if {@code source} or {@code pos} is null.
       
   294      */
       
   295     @Override
       
   296     public final Object parseObject(String source, ParsePosition pos) {
       
   297         return parse(source, pos);
       
   298     }
       
   299 
       
   300    /**
       
   301      * Specialization of format.
       
   302      *
       
   303      * @param number the double number to format
       
   304      * @return the formatted String
       
   305      * @exception        ArithmeticException if rounding is needed with rounding
       
   306      *                   mode being set to RoundingMode.UNNECESSARY
       
   307      * @see java.text.Format#format
       
   308      */
       
   309     public final String format(double number) {
       
   310         // Use fast-path for double result if that works
       
   311         String result = fastFormat(number);
       
   312         if (result != null)
       
   313             return result;
       
   314 
       
   315         return format(number, new StringBuffer(),
       
   316                       DontCareFieldPosition.INSTANCE).toString();
       
   317     }
       
   318 
       
   319     /*
       
   320      * fastFormat() is supposed to be implemented in concrete subclasses only.
       
   321      * Default implem always returns null.
       
   322      */
       
   323     String fastFormat(double number) { return null; }
       
   324 
       
   325    /**
       
   326      * Specialization of format.
       
   327      *
       
   328      * @param number the long number to format
       
   329      * @return the formatted String
       
   330      * @exception        ArithmeticException if rounding is needed with rounding
       
   331      *                   mode being set to RoundingMode.UNNECESSARY
       
   332      * @see java.text.Format#format
       
   333      */
       
   334     public final String format(long number) {
       
   335         return format(number, new StringBuffer(),
       
   336                       DontCareFieldPosition.INSTANCE).toString();
       
   337     }
       
   338 
       
   339    /**
       
   340      * Specialization of format.
       
   341      *
       
   342      * @param number     the double number to format
       
   343      * @param toAppendTo the StringBuffer to which the formatted text is to be
       
   344      *                   appended
       
   345      * @param pos        the field position
       
   346      * @return the formatted StringBuffer
       
   347      * @exception        ArithmeticException if rounding is needed with rounding
       
   348      *                   mode being set to RoundingMode.UNNECESSARY
       
   349      * @see java.text.Format#format
       
   350      */
       
   351     public abstract StringBuffer format(double number,
       
   352                                         StringBuffer toAppendTo,
       
   353                                         FieldPosition pos);
       
   354 
       
   355    /**
       
   356      * Specialization of format.
       
   357      *
       
   358      * @param number     the long number to format
       
   359      * @param toAppendTo the StringBuffer to which the formatted text is to be
       
   360      *                   appended
       
   361      * @param pos        the field position
       
   362      * @return the formatted StringBuffer
       
   363      * @exception        ArithmeticException if rounding is needed with rounding
       
   364      *                   mode being set to RoundingMode.UNNECESSARY
       
   365      * @see java.text.Format#format
       
   366      */
       
   367     public abstract StringBuffer format(long number,
       
   368                                         StringBuffer toAppendTo,
       
   369                                         FieldPosition pos);
       
   370 
       
   371    /**
       
   372      * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
       
   373      * Long.MAX_VALUE] and with no decimals), otherwise a Double.
       
   374      * If IntegerOnly is set, will stop at a decimal
       
   375      * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
       
   376      * after the 1).
       
   377      * Does not throw an exception; if no object can be parsed, index is
       
   378      * unchanged!
       
   379      *
       
   380      * @param source the String to parse
       
   381      * @param parsePosition the parse position
       
   382      * @return the parsed value
       
   383      * @see java.text.NumberFormat#isParseIntegerOnly
       
   384      * @see java.text.Format#parseObject
       
   385      */
       
   386     public abstract Number parse(String source, ParsePosition parsePosition);
       
   387 
       
   388     /**
       
   389      * Parses text from the beginning of the given string to produce a number.
       
   390      * The method may not use the entire text of the given string.
       
   391      * <p>
       
   392      * See the {@link #parse(String, ParsePosition)} method for more information
       
   393      * on number parsing.
       
   394      *
       
   395      * @param source A <code>String</code> whose beginning should be parsed.
       
   396      * @return A <code>Number</code> parsed from the string.
       
   397      * @exception ParseException if the beginning of the specified string
       
   398      *            cannot be parsed.
       
   399      */
       
   400     public Number parse(String source) throws ParseException {
       
   401         ParsePosition parsePosition = new ParsePosition(0);
       
   402         Number result = parse(source, parsePosition);
       
   403         if (parsePosition.index == 0) {
       
   404             throw new ParseException("Unparseable number: \"" + source + "\"",
       
   405                                      parsePosition.errorIndex);
       
   406         }
       
   407         return result;
       
   408     }
       
   409 
       
   410     /**
       
   411      * Returns true if this format will parse numbers as integers only.
       
   412      * For example in the English locale, with ParseIntegerOnly true, the
       
   413      * string "1234." would be parsed as the integer value 1234 and parsing
       
   414      * would stop at the "." character.  Of course, the exact format accepted
       
   415      * by the parse operation is locale dependent and determined by sub-classes
       
   416      * of NumberFormat.
       
   417      *
       
   418      * @return {@code true} if numbers should be parsed as integers only;
       
   419      *         {@code false} otherwise
       
   420      */
       
   421     public boolean isParseIntegerOnly() {
       
   422         return parseIntegerOnly;
       
   423     }
       
   424 
       
   425     /**
       
   426      * Sets whether or not numbers should be parsed as integers only.
       
   427      *
       
   428      * @param value {@code true} if numbers should be parsed as integers only;
       
   429      *              {@code false} otherwise
       
   430      * @see #isParseIntegerOnly
       
   431      */
       
   432     public void setParseIntegerOnly(boolean value) {
       
   433         parseIntegerOnly = value;
       
   434     }
       
   435 
       
   436     //============== Locale Stuff =====================
       
   437 
       
   438     /**
       
   439      * Returns a general-purpose number format for the current default
       
   440      * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
       
   441      * This is the same as calling
       
   442      * {@link #getNumberInstance() getNumberInstance()}.
       
   443      *
       
   444      * @return the {@code NumberFormat} instance for general-purpose number
       
   445      * formatting
       
   446      */
       
   447     public static final NumberFormat getInstance() {
       
   448         return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
       
   449     }
       
   450 
       
   451     /**
       
   452      * Returns a general-purpose number format for the specified locale.
       
   453      * This is the same as calling
       
   454      * {@link #getNumberInstance(java.util.Locale) getNumberInstance(inLocale)}.
       
   455      *
       
   456      * @param inLocale the desired locale
       
   457      * @return the {@code NumberFormat} instance for general-purpose number
       
   458      * formatting
       
   459      */
       
   460     public static NumberFormat getInstance(Locale inLocale) {
       
   461         return getInstance(inLocale, NUMBERSTYLE);
       
   462     }
       
   463 
       
   464     /**
       
   465      * Returns a general-purpose number format for the current default
       
   466      * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
       
   467      * <p>This is equivalent to calling
       
   468      * {@link #getNumberInstance(Locale)
       
   469      *     getNumberInstance(Locale.getDefault(Locale.Category.FORMAT))}.
       
   470      *
       
   471      * @return the {@code NumberFormat} instance for general-purpose number
       
   472      * formatting
       
   473      * @see java.util.Locale#getDefault(java.util.Locale.Category)
       
   474      * @see java.util.Locale.Category#FORMAT
       
   475      */
       
   476     public static final NumberFormat getNumberInstance() {
       
   477         return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
       
   478     }
       
   479 
       
   480     /**
       
   481      * Returns a general-purpose number format for the specified locale.
       
   482      *
       
   483      * @param inLocale the desired locale
       
   484      * @return the {@code NumberFormat} instance for general-purpose number
       
   485      * formatting
       
   486      */
       
   487     public static NumberFormat getNumberInstance(Locale inLocale) {
       
   488         return getInstance(inLocale, NUMBERSTYLE);
       
   489     }
       
   490 
       
   491     /**
       
   492      * Returns an integer number format for the current default
       
   493      * {@link java.util.Locale.Category#FORMAT FORMAT} locale. The
       
   494      * returned number format is configured to round floating point numbers
       
   495      * to the nearest integer using half-even rounding (see {@link
       
   496      * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
       
   497      * and to parse only the integer part of an input string (see {@link
       
   498      * #isParseIntegerOnly isParseIntegerOnly}).
       
   499      * <p>This is equivalent to calling
       
   500      * {@link #getIntegerInstance(Locale)
       
   501      *     getIntegerInstance(Locale.getDefault(Locale.Category.FORMAT))}.
       
   502      *
       
   503      * @see #getRoundingMode()
       
   504      * @see java.util.Locale#getDefault(java.util.Locale.Category)
       
   505      * @see java.util.Locale.Category#FORMAT
       
   506      * @return a number format for integer values
       
   507      * @since 1.4
       
   508      */
       
   509     public static final NumberFormat getIntegerInstance() {
       
   510         return getInstance(Locale.getDefault(Locale.Category.FORMAT), INTEGERSTYLE);
       
   511     }
       
   512 
       
   513     /**
       
   514      * Returns an integer number format for the specified locale. The
       
   515      * returned number format is configured to round floating point numbers
       
   516      * to the nearest integer using half-even rounding (see {@link
       
   517      * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,
       
   518      * and to parse only the integer part of an input string (see {@link
       
   519      * #isParseIntegerOnly isParseIntegerOnly}).
       
   520      *
       
   521      * @param inLocale the desired locale
       
   522      * @see #getRoundingMode()
       
   523      * @return a number format for integer values
       
   524      * @since 1.4
       
   525      */
       
   526     public static NumberFormat getIntegerInstance(Locale inLocale) {
       
   527         return getInstance(inLocale, INTEGERSTYLE);
       
   528     }
       
   529 
       
   530     /**
       
   531      * Returns a currency format for the current default
       
   532      * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
       
   533      * <p>This is equivalent to calling
       
   534      * {@link #getCurrencyInstance(Locale)
       
   535      *     getCurrencyInstance(Locale.getDefault(Locale.Category.FORMAT))}.
       
   536      *
       
   537      * @return the {@code NumberFormat} instance for currency formatting
       
   538      * @see java.util.Locale#getDefault(java.util.Locale.Category)
       
   539      * @see java.util.Locale.Category#FORMAT
       
   540      */
       
   541     public static final NumberFormat getCurrencyInstance() {
       
   542         return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE);
       
   543     }
       
   544 
       
   545     /**
       
   546      * Returns a currency format for the specified locale.
       
   547      *
       
   548      * @param inLocale the desired locale
       
   549      * @return the {@code NumberFormat} instance for currency formatting
       
   550      */
       
   551     public static NumberFormat getCurrencyInstance(Locale inLocale) {
       
   552         return getInstance(inLocale, CURRENCYSTYLE);
       
   553     }
       
   554 
       
   555     /**
       
   556      * Returns a percentage format for the current default
       
   557      * {@link java.util.Locale.Category#FORMAT FORMAT} locale.
       
   558      * <p>This is equivalent to calling
       
   559      * {@link #getPercentInstance(Locale)
       
   560      *     getPercentInstance(Locale.getDefault(Locale.Category.FORMAT))}.
       
   561      *
       
   562      * @return the {@code NumberFormat} instance for percentage formatting
       
   563      * @see java.util.Locale#getDefault(java.util.Locale.Category)
       
   564      * @see java.util.Locale.Category#FORMAT
       
   565      */
       
   566     public static final NumberFormat getPercentInstance() {
       
   567         return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE);
       
   568     }
       
   569 
       
   570     /**
       
   571      * Returns a percentage format for the specified locale.
       
   572      *
       
   573      * @param inLocale the desired locale
       
   574      * @return the {@code NumberFormat} instance for percentage formatting
       
   575      */
       
   576     public static NumberFormat getPercentInstance(Locale inLocale) {
       
   577         return getInstance(inLocale, PERCENTSTYLE);
       
   578     }
       
   579 
       
   580     /**
       
   581      * Returns a scientific format for the current default locale.
       
   582      */
       
   583     /*public*/ final static NumberFormat getScientificInstance() {
       
   584         return getInstance(Locale.getDefault(Locale.Category.FORMAT), SCIENTIFICSTYLE);
       
   585     }
       
   586 
       
   587     /**
       
   588      * Returns a scientific format for the specified locale.
       
   589      *
       
   590      * @param inLocale the desired locale
       
   591      */
       
   592     /*public*/ static NumberFormat getScientificInstance(Locale inLocale) {
       
   593         return getInstance(inLocale, SCIENTIFICSTYLE);
       
   594     }
       
   595 
       
   596     /**
       
   597      * Returns an array of all locales for which the
       
   598      * <code>get*Instance</code> methods of this class can return
       
   599      * localized instances.
       
   600      * The returned array represents the union of locales supported by the Java
       
   601      * runtime and by installed
       
   602      * {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations.
       
   603      * It must contain at least a <code>Locale</code> instance equal to
       
   604      * {@link java.util.Locale#US Locale.US}.
       
   605      *
       
   606      * @return An array of locales for which localized
       
   607      *         <code>NumberFormat</code> instances are available.
       
   608      */
       
   609     public static Locale[] getAvailableLocales() {
       
   610         LocaleServiceProviderPool pool =
       
   611             LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
       
   612         return pool.getAvailableLocales();
       
   613     }
       
   614 
       
   615     /**
       
   616      * Overrides hashCode.
       
   617      */
       
   618     @Override
       
   619     public int hashCode() {
       
   620         return maximumIntegerDigits * 37 + maxFractionDigits;
       
   621         // just enough fields for a reasonable distribution
       
   622     }
       
   623 
       
   624     /**
       
   625      * Overrides equals.
       
   626      */
       
   627     @Override
       
   628     public boolean equals(Object obj) {
       
   629         if (obj == null) {
       
   630             return false;
       
   631         }
       
   632         if (this == obj) {
       
   633             return true;
       
   634         }
       
   635         if (getClass() != obj.getClass()) {
       
   636             return false;
       
   637         }
       
   638         NumberFormat other = (NumberFormat) obj;
       
   639         return (maximumIntegerDigits == other.maximumIntegerDigits
       
   640             && minimumIntegerDigits == other.minimumIntegerDigits
       
   641             && maximumFractionDigits == other.maximumFractionDigits
       
   642             && minimumFractionDigits == other.minimumFractionDigits
       
   643             && groupingUsed == other.groupingUsed
       
   644             && parseIntegerOnly == other.parseIntegerOnly);
       
   645     }
       
   646 
       
   647     /**
       
   648      * Overrides Cloneable.
       
   649      */
       
   650     @Override
       
   651     public Object clone() {
       
   652         NumberFormat other = (NumberFormat) super.clone();
       
   653         return other;
       
   654     }
       
   655 
       
   656     /**
       
   657      * Returns true if grouping is used in this format. For example, in the
       
   658      * English locale, with grouping on, the number 1234567 might be formatted
       
   659      * as "1,234,567". The grouping separator as well as the size of each group
       
   660      * is locale dependent and is determined by sub-classes of NumberFormat.
       
   661      *
       
   662      * @return {@code true} if grouping is used;
       
   663      *         {@code false} otherwise
       
   664      * @see #setGroupingUsed
       
   665      */
       
   666     public boolean isGroupingUsed() {
       
   667         return groupingUsed;
       
   668     }
       
   669 
       
   670     /**
       
   671      * Set whether or not grouping will be used in this format.
       
   672      *
       
   673      * @param newValue {@code true} if grouping is used;
       
   674      *                 {@code false} otherwise
       
   675      * @see #isGroupingUsed
       
   676      */
       
   677     public void setGroupingUsed(boolean newValue) {
       
   678         groupingUsed = newValue;
       
   679     }
       
   680 
       
   681     /**
       
   682      * Returns the maximum number of digits allowed in the integer portion of a
       
   683      * number.
       
   684      *
       
   685      * @return the maximum number of digits
       
   686      * @see #setMaximumIntegerDigits
       
   687      */
       
   688     public int getMaximumIntegerDigits() {
       
   689         return maximumIntegerDigits;
       
   690     }
       
   691 
       
   692     /**
       
   693      * Sets the maximum number of digits allowed in the integer portion of a
       
   694      * number. maximumIntegerDigits must be &ge; minimumIntegerDigits.  If the
       
   695      * new value for maximumIntegerDigits is less than the current value
       
   696      * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
       
   697      * the new value.
       
   698      *
       
   699      * @param newValue the maximum number of integer digits to be shown; if
       
   700      * less than zero, then zero is used. The concrete subclass may enforce an
       
   701      * upper limit to this value appropriate to the numeric type being formatted.
       
   702      * @see #getMaximumIntegerDigits
       
   703      */
       
   704     public void setMaximumIntegerDigits(int newValue) {
       
   705         maximumIntegerDigits = Math.max(0,newValue);
       
   706         if (minimumIntegerDigits > maximumIntegerDigits) {
       
   707             minimumIntegerDigits = maximumIntegerDigits;
       
   708         }
       
   709     }
       
   710 
       
   711     /**
       
   712      * Returns the minimum number of digits allowed in the integer portion of a
       
   713      * number.
       
   714      *
       
   715      * @return the minimum number of digits
       
   716      * @see #setMinimumIntegerDigits
       
   717      */
       
   718     public int getMinimumIntegerDigits() {
       
   719         return minimumIntegerDigits;
       
   720     }
       
   721 
       
   722     /**
       
   723      * Sets the minimum number of digits allowed in the integer portion of a
       
   724      * number. minimumIntegerDigits must be &le; maximumIntegerDigits.  If the
       
   725      * new value for minimumIntegerDigits exceeds the current value
       
   726      * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
       
   727      * the new value
       
   728      *
       
   729      * @param newValue the minimum number of integer digits to be shown; if
       
   730      * less than zero, then zero is used. The concrete subclass may enforce an
       
   731      * upper limit to this value appropriate to the numeric type being formatted.
       
   732      * @see #getMinimumIntegerDigits
       
   733      */
       
   734     public void setMinimumIntegerDigits(int newValue) {
       
   735         minimumIntegerDigits = Math.max(0,newValue);
       
   736         if (minimumIntegerDigits > maximumIntegerDigits) {
       
   737             maximumIntegerDigits = minimumIntegerDigits;
       
   738         }
       
   739     }
       
   740 
       
   741     /**
       
   742      * Returns the maximum number of digits allowed in the fraction portion of a
       
   743      * number.
       
   744      *
       
   745      * @return the maximum number of digits.
       
   746      * @see #setMaximumFractionDigits
       
   747      */
       
   748     public int getMaximumFractionDigits() {
       
   749         return maximumFractionDigits;
       
   750     }
       
   751 
       
   752     /**
       
   753      * Sets the maximum number of digits allowed in the fraction portion of a
       
   754      * number. maximumFractionDigits must be &ge; minimumFractionDigits.  If the
       
   755      * new value for maximumFractionDigits is less than the current value
       
   756      * of minimumFractionDigits, then minimumFractionDigits will also be set to
       
   757      * the new value.
       
   758      *
       
   759      * @param newValue the maximum number of fraction digits to be shown; if
       
   760      * less than zero, then zero is used. The concrete subclass may enforce an
       
   761      * upper limit to this value appropriate to the numeric type being formatted.
       
   762      * @see #getMaximumFractionDigits
       
   763      */
       
   764     public void setMaximumFractionDigits(int newValue) {
       
   765         maximumFractionDigits = Math.max(0,newValue);
       
   766         if (maximumFractionDigits < minimumFractionDigits) {
       
   767             minimumFractionDigits = maximumFractionDigits;
       
   768         }
       
   769     }
       
   770 
       
   771     /**
       
   772      * Returns the minimum number of digits allowed in the fraction portion of a
       
   773      * number.
       
   774      *
       
   775      * @return the minimum number of digits
       
   776      * @see #setMinimumFractionDigits
       
   777      */
       
   778     public int getMinimumFractionDigits() {
       
   779         return minimumFractionDigits;
       
   780     }
       
   781 
       
   782     /**
       
   783      * Sets the minimum number of digits allowed in the fraction portion of a
       
   784      * number. minimumFractionDigits must be &le; maximumFractionDigits.  If the
       
   785      * new value for minimumFractionDigits exceeds the current value
       
   786      * of maximumFractionDigits, then maximumIntegerDigits will also be set to
       
   787      * the new value
       
   788      *
       
   789      * @param newValue the minimum number of fraction digits to be shown; if
       
   790      * less than zero, then zero is used. The concrete subclass may enforce an
       
   791      * upper limit to this value appropriate to the numeric type being formatted.
       
   792      * @see #getMinimumFractionDigits
       
   793      */
       
   794     public void setMinimumFractionDigits(int newValue) {
       
   795         minimumFractionDigits = Math.max(0,newValue);
       
   796         if (maximumFractionDigits < minimumFractionDigits) {
       
   797             maximumFractionDigits = minimumFractionDigits;
       
   798         }
       
   799     }
       
   800 
       
   801     /**
       
   802      * Gets the currency used by this number format when formatting
       
   803      * currency values. The initial value is derived in a locale dependent
       
   804      * way. The returned value may be null if no valid
       
   805      * currency could be determined and no currency has been set using
       
   806      * {@link #setCurrency(java.util.Currency) setCurrency}.
       
   807      * <p>
       
   808      * The default implementation throws
       
   809      * <code>UnsupportedOperationException</code>.
       
   810      *
       
   811      * @return the currency used by this number format, or <code>null</code>
       
   812      * @exception UnsupportedOperationException if the number format class
       
   813      * doesn't implement currency formatting
       
   814      * @since 1.4
       
   815      */
       
   816     public Currency getCurrency() {
       
   817         throw new UnsupportedOperationException();
       
   818     }
       
   819 
       
   820     /**
       
   821      * Sets the currency used by this number format when formatting
       
   822      * currency values. This does not update the minimum or maximum
       
   823      * number of fraction digits used by the number format.
       
   824      * <p>
       
   825      * The default implementation throws
       
   826      * <code>UnsupportedOperationException</code>.
       
   827      *
       
   828      * @param currency the new currency to be used by this number format
       
   829      * @exception UnsupportedOperationException if the number format class
       
   830      * doesn't implement currency formatting
       
   831      * @exception NullPointerException if <code>currency</code> is null
       
   832      * @since 1.4
       
   833      */
       
   834     public void setCurrency(Currency currency) {
       
   835         throw new UnsupportedOperationException();
       
   836     }
       
   837 
       
   838     /**
       
   839      * Gets the {@link java.math.RoundingMode} used in this NumberFormat.
       
   840      * The default implementation of this method in NumberFormat
       
   841      * always throws {@link java.lang.UnsupportedOperationException}.
       
   842      * Subclasses which handle different rounding modes should override
       
   843      * this method.
       
   844      *
       
   845      * @exception UnsupportedOperationException The default implementation
       
   846      *     always throws this exception
       
   847      * @return The <code>RoundingMode</code> used for this NumberFormat.
       
   848      * @see #setRoundingMode(RoundingMode)
       
   849      * @since 1.6
       
   850      */
       
   851     public RoundingMode getRoundingMode() {
       
   852         throw new UnsupportedOperationException();
       
   853     }
       
   854 
       
   855     /**
       
   856      * Sets the {@link java.math.RoundingMode} used in this NumberFormat.
       
   857      * The default implementation of this method in NumberFormat always
       
   858      * throws {@link java.lang.UnsupportedOperationException}.
       
   859      * Subclasses which handle different rounding modes should override
       
   860      * this method.
       
   861      *
       
   862      * @exception UnsupportedOperationException The default implementation
       
   863      *     always throws this exception
       
   864      * @exception NullPointerException if <code>roundingMode</code> is null
       
   865      * @param roundingMode The <code>RoundingMode</code> to be used
       
   866      * @see #getRoundingMode()
       
   867      * @since 1.6
       
   868      */
       
   869     public void setRoundingMode(RoundingMode roundingMode) {
       
   870         throw new UnsupportedOperationException();
       
   871     }
       
   872 
       
   873     // =======================privates===============================
       
   874 
       
   875     private static NumberFormat getInstance(Locale desiredLocale,
       
   876                                            int choice) {
       
   877         LocaleProviderAdapter adapter;
       
   878         adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class,
       
   879                                                    desiredLocale);
       
   880         NumberFormat numberFormat = getInstance(adapter, desiredLocale, choice);
       
   881         if (numberFormat == null) {
       
   882             numberFormat = getInstance(LocaleProviderAdapter.forJRE(),
       
   883                                        desiredLocale, choice);
       
   884         }
       
   885         return numberFormat;
       
   886     }
       
   887 
       
   888     private static NumberFormat getInstance(LocaleProviderAdapter adapter,
       
   889                                             Locale locale, int choice) {
       
   890         NumberFormatProvider provider = adapter.getNumberFormatProvider();
       
   891         NumberFormat numberFormat = null;
       
   892         switch (choice) {
       
   893         case NUMBERSTYLE:
       
   894             numberFormat = provider.getNumberInstance(locale);
       
   895             break;
       
   896         case PERCENTSTYLE:
       
   897             numberFormat = provider.getPercentInstance(locale);
       
   898             break;
       
   899         case CURRENCYSTYLE:
       
   900             numberFormat = provider.getCurrencyInstance(locale);
       
   901             break;
       
   902         case INTEGERSTYLE:
       
   903             numberFormat = provider.getIntegerInstance(locale);
       
   904             break;
       
   905         }
       
   906         return numberFormat;
       
   907     }
       
   908 
       
   909     /**
       
   910      * First, read in the default serializable data.
       
   911      *
       
   912      * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
       
   913      * the stream was written by JDK 1.1,
       
   914      * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
       
   915      * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
       
   916      * since the <code>int</code> fields were not present in JDK 1.1.
       
   917      * Finally, set serialVersionOnStream back to the maximum allowed value so that
       
   918      * default serialization will work properly if this object is streamed out again.
       
   919      *
       
   920      * <p>If <code>minimumIntegerDigits</code> is greater than
       
   921      * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code>
       
   922      * is greater than <code>maximumFractionDigits</code>, then the stream data
       
   923      * is invalid and this method throws an <code>InvalidObjectException</code>.
       
   924      * In addition, if any of these values is negative, then this method throws
       
   925      * an <code>InvalidObjectException</code>.
       
   926      *
       
   927      * @since 1.2
       
   928      */
       
   929     private void readObject(ObjectInputStream stream)
       
   930          throws IOException, ClassNotFoundException
       
   931     {
       
   932         stream.defaultReadObject();
       
   933         if (serialVersionOnStream < 1) {
       
   934             // Didn't have additional int fields, reassign to use them.
       
   935             maximumIntegerDigits = maxIntegerDigits;
       
   936             minimumIntegerDigits = minIntegerDigits;
       
   937             maximumFractionDigits = maxFractionDigits;
       
   938             minimumFractionDigits = minFractionDigits;
       
   939         }
       
   940         if (minimumIntegerDigits > maximumIntegerDigits ||
       
   941             minimumFractionDigits > maximumFractionDigits ||
       
   942             minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
       
   943             throw new InvalidObjectException("Digit count range invalid");
       
   944         }
       
   945         serialVersionOnStream = currentSerialVersion;
       
   946     }
       
   947 
       
   948     /**
       
   949      * Write out the default serializable data, after first setting
       
   950      * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
       
   951      * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
       
   952      * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
       
   953      * with the JDK 1.1 version of the stream format.
       
   954      *
       
   955      * @since 1.2
       
   956      */
       
   957     private void writeObject(ObjectOutputStream stream)
       
   958          throws IOException
       
   959     {
       
   960         maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ?
       
   961                            Byte.MAX_VALUE : (byte)maximumIntegerDigits;
       
   962         minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ?
       
   963                            Byte.MAX_VALUE : (byte)minimumIntegerDigits;
       
   964         maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ?
       
   965                             Byte.MAX_VALUE : (byte)maximumFractionDigits;
       
   966         minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ?
       
   967                             Byte.MAX_VALUE : (byte)minimumFractionDigits;
       
   968         stream.defaultWriteObject();
       
   969     }
       
   970 
       
   971     // Constants used by factory methods to specify a style of format.
       
   972     private static final int NUMBERSTYLE = 0;
       
   973     private static final int CURRENCYSTYLE = 1;
       
   974     private static final int PERCENTSTYLE = 2;
       
   975     private static final int SCIENTIFICSTYLE = 3;
       
   976     private static final int INTEGERSTYLE = 4;
       
   977 
       
   978     /**
       
   979      * True if the grouping (i.e. thousands) separator is used when
       
   980      * formatting and parsing numbers.
       
   981      *
       
   982      * @serial
       
   983      * @see #isGroupingUsed
       
   984      */
       
   985     private boolean groupingUsed = true;
       
   986 
       
   987     /**
       
   988      * The maximum number of digits allowed in the integer portion of a
       
   989      * number.  <code>maxIntegerDigits</code> must be greater than or equal to
       
   990      * <code>minIntegerDigits</code>.
       
   991      * <p>
       
   992      * <strong>Note:</strong> This field exists only for serialization
       
   993      * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
       
   994      * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
       
   995      * When writing to a stream, <code>maxIntegerDigits</code> is set to
       
   996      * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
       
   997      * whichever is smaller.  When reading from a stream, this field is used
       
   998      * only if <code>serialVersionOnStream</code> is less than 1.
       
   999      *
       
  1000      * @serial
       
  1001      * @see #getMaximumIntegerDigits
       
  1002      */
       
  1003     private byte    maxIntegerDigits = 40;
       
  1004 
       
  1005     /**
       
  1006      * The minimum number of digits allowed in the integer portion of a
       
  1007      * number.  <code>minimumIntegerDigits</code> must be less than or equal to
       
  1008      * <code>maximumIntegerDigits</code>.
       
  1009      * <p>
       
  1010      * <strong>Note:</strong> This field exists only for serialization
       
  1011      * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
       
  1012      * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
       
  1013      * When writing to a stream, <code>minIntegerDigits</code> is set to
       
  1014      * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
       
  1015      * whichever is smaller.  When reading from a stream, this field is used
       
  1016      * only if <code>serialVersionOnStream</code> is less than 1.
       
  1017      *
       
  1018      * @serial
       
  1019      * @see #getMinimumIntegerDigits
       
  1020      */
       
  1021     private byte    minIntegerDigits = 1;
       
  1022 
       
  1023     /**
       
  1024      * The maximum number of digits allowed in the fractional portion of a
       
  1025      * number.  <code>maximumFractionDigits</code> must be greater than or equal to
       
  1026      * <code>minimumFractionDigits</code>.
       
  1027      * <p>
       
  1028      * <strong>Note:</strong> This field exists only for serialization
       
  1029      * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
       
  1030      * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
       
  1031      * When writing to a stream, <code>maxFractionDigits</code> is set to
       
  1032      * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
       
  1033      * whichever is smaller.  When reading from a stream, this field is used
       
  1034      * only if <code>serialVersionOnStream</code> is less than 1.
       
  1035      *
       
  1036      * @serial
       
  1037      * @see #getMaximumFractionDigits
       
  1038      */
       
  1039     private byte    maxFractionDigits = 3;    // invariant, >= minFractionDigits
       
  1040 
       
  1041     /**
       
  1042      * The minimum number of digits allowed in the fractional portion of a
       
  1043      * number.  <code>minimumFractionDigits</code> must be less than or equal to
       
  1044      * <code>maximumFractionDigits</code>.
       
  1045      * <p>
       
  1046      * <strong>Note:</strong> This field exists only for serialization
       
  1047      * compatibility with JDK 1.1.  In Java platform 2 v1.2 and higher, the new
       
  1048      * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
       
  1049      * When writing to a stream, <code>minFractionDigits</code> is set to
       
  1050      * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
       
  1051      * whichever is smaller.  When reading from a stream, this field is used
       
  1052      * only if <code>serialVersionOnStream</code> is less than 1.
       
  1053      *
       
  1054      * @serial
       
  1055      * @see #getMinimumFractionDigits
       
  1056      */
       
  1057     private byte    minFractionDigits = 0;
       
  1058 
       
  1059     /**
       
  1060      * True if this format will parse numbers as integers only.
       
  1061      *
       
  1062      * @serial
       
  1063      * @see #isParseIntegerOnly
       
  1064      */
       
  1065     private boolean parseIntegerOnly = false;
       
  1066 
       
  1067     // new fields for 1.2.  byte is too small for integer digits.
       
  1068 
       
  1069     /**
       
  1070      * The maximum number of digits allowed in the integer portion of a
       
  1071      * number.  <code>maximumIntegerDigits</code> must be greater than or equal to
       
  1072      * <code>minimumIntegerDigits</code>.
       
  1073      *
       
  1074      * @serial
       
  1075      * @since 1.2
       
  1076      * @see #getMaximumIntegerDigits
       
  1077      */
       
  1078     private int    maximumIntegerDigits = 40;
       
  1079 
       
  1080     /**
       
  1081      * The minimum number of digits allowed in the integer portion of a
       
  1082      * number.  <code>minimumIntegerDigits</code> must be less than or equal to
       
  1083      * <code>maximumIntegerDigits</code>.
       
  1084      *
       
  1085      * @serial
       
  1086      * @since 1.2
       
  1087      * @see #getMinimumIntegerDigits
       
  1088      */
       
  1089     private int    minimumIntegerDigits = 1;
       
  1090 
       
  1091     /**
       
  1092      * The maximum number of digits allowed in the fractional portion of a
       
  1093      * number.  <code>maximumFractionDigits</code> must be greater than or equal to
       
  1094      * <code>minimumFractionDigits</code>.
       
  1095      *
       
  1096      * @serial
       
  1097      * @since 1.2
       
  1098      * @see #getMaximumFractionDigits
       
  1099      */
       
  1100     private int    maximumFractionDigits = 3;    // invariant, >= minFractionDigits
       
  1101 
       
  1102     /**
       
  1103      * The minimum number of digits allowed in the fractional portion of a
       
  1104      * number.  <code>minimumFractionDigits</code> must be less than or equal to
       
  1105      * <code>maximumFractionDigits</code>.
       
  1106      *
       
  1107      * @serial
       
  1108      * @since 1.2
       
  1109      * @see #getMinimumFractionDigits
       
  1110      */
       
  1111     private int    minimumFractionDigits = 0;
       
  1112 
       
  1113     static final int currentSerialVersion = 1;
       
  1114 
       
  1115     /**
       
  1116      * Describes the version of <code>NumberFormat</code> present on the stream.
       
  1117      * Possible values are:
       
  1118      * <ul>
       
  1119      * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
       
  1120      *     In this version, the <code>int</code> fields such as
       
  1121      *     <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
       
  1122      *     fields such as <code>maxIntegerDigits</code> are used instead.
       
  1123      *
       
  1124      * <li><b>1</b>: the 1.2 version of the stream format.  The values of the
       
  1125      *     <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
       
  1126      *     and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
       
  1127      *     are used instead.
       
  1128      * </ul>
       
  1129      * When streaming out a <code>NumberFormat</code>, the most recent format
       
  1130      * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
       
  1131      * is always written.
       
  1132      *
       
  1133      * @serial
       
  1134      * @since 1.2
       
  1135      */
       
  1136     private int serialVersionOnStream = currentSerialVersion;
       
  1137 
       
  1138     // Removed "implements Cloneable" clause.  Needs to update serialization
       
  1139     // ID for backward compatibility.
       
  1140     static final long serialVersionUID = -2308460125733713944L;
       
  1141 
       
  1142 
       
  1143     //
       
  1144     // class for AttributedCharacterIterator attributes
       
  1145     //
       
  1146     /**
       
  1147      * Defines constants that are used as attribute keys in the
       
  1148      * <code>AttributedCharacterIterator</code> returned
       
  1149      * from <code>NumberFormat.formatToCharacterIterator</code> and as
       
  1150      * field identifiers in <code>FieldPosition</code>.
       
  1151      *
       
  1152      * @since 1.4
       
  1153      */
       
  1154     public static class Field extends Format.Field {
       
  1155 
       
  1156         // Proclaim serial compatibility with 1.4 FCS
       
  1157         private static final long serialVersionUID = 7494728892700160890L;
       
  1158 
       
  1159         // table of all instances in this class, used by readResolve
       
  1160         private static final Map<String, Field> instanceMap = new HashMap<>(11);
       
  1161 
       
  1162         /**
       
  1163          * Creates a Field instance with the specified
       
  1164          * name.
       
  1165          *
       
  1166          * @param name Name of the attribute
       
  1167          */
       
  1168         protected Field(String name) {
       
  1169             super(name);
       
  1170             if (this.getClass() == NumberFormat.Field.class) {
       
  1171                 instanceMap.put(name, this);
       
  1172             }
       
  1173         }
       
  1174 
       
  1175         /**
       
  1176          * Resolves instances being deserialized to the predefined constants.
       
  1177          *
       
  1178          * @throws InvalidObjectException if the constant could not be resolved.
       
  1179          * @return resolved NumberFormat.Field constant
       
  1180          */
       
  1181         @Override
       
  1182         protected Object readResolve() throws InvalidObjectException {
       
  1183             if (this.getClass() != NumberFormat.Field.class) {
       
  1184                 throw new InvalidObjectException("subclass didn't correctly implement readResolve");
       
  1185             }
       
  1186 
       
  1187             Object instance = instanceMap.get(getName());
       
  1188             if (instance != null) {
       
  1189                 return instance;
       
  1190             } else {
       
  1191                 throw new InvalidObjectException("unknown attribute name");
       
  1192             }
       
  1193         }
       
  1194 
       
  1195         /**
       
  1196          * Constant identifying the integer field.
       
  1197          */
       
  1198         public static final Field INTEGER = new Field("integer");
       
  1199 
       
  1200         /**
       
  1201          * Constant identifying the fraction field.
       
  1202          */
       
  1203         public static final Field FRACTION = new Field("fraction");
       
  1204 
       
  1205         /**
       
  1206          * Constant identifying the exponent field.
       
  1207          */
       
  1208         public static final Field EXPONENT = new Field("exponent");
       
  1209 
       
  1210         /**
       
  1211          * Constant identifying the decimal separator field.
       
  1212          */
       
  1213         public static final Field DECIMAL_SEPARATOR =
       
  1214                             new Field("decimal separator");
       
  1215 
       
  1216         /**
       
  1217          * Constant identifying the sign field.
       
  1218          */
       
  1219         public static final Field SIGN = new Field("sign");
       
  1220 
       
  1221         /**
       
  1222          * Constant identifying the grouping separator field.
       
  1223          */
       
  1224         public static final Field GROUPING_SEPARATOR =
       
  1225                             new Field("grouping separator");
       
  1226 
       
  1227         /**
       
  1228          * Constant identifying the exponent symbol field.
       
  1229          */
       
  1230         public static final Field EXPONENT_SYMBOL = new
       
  1231                             Field("exponent symbol");
       
  1232 
       
  1233         /**
       
  1234          * Constant identifying the percent field.
       
  1235          */
       
  1236         public static final Field PERCENT = new Field("percent");
       
  1237 
       
  1238         /**
       
  1239          * Constant identifying the permille field.
       
  1240          */
       
  1241         public static final Field PERMILLE = new Field("per mille");
       
  1242 
       
  1243         /**
       
  1244          * Constant identifying the currency field.
       
  1245          */
       
  1246         public static final Field CURRENCY = new Field("currency");
       
  1247 
       
  1248         /**
       
  1249          * Constant identifying the exponent sign field.
       
  1250          */
       
  1251         public static final Field EXPONENT_SIGN = new Field("exponent sign");
       
  1252     }
       
  1253 }