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