• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GENERATED SOURCE. DO NOT MODIFY. */
2 // © 2016 and later: Unicode, Inc. and others.
3 // License & terms of use: http://www.unicode.org/copyright.html#License
4 /*
5  *******************************************************************************
6  * Copyright (C) 1996-2016, International Business Machines Corporation and
7  * others. All Rights Reserved.
8  *******************************************************************************
9  */
10 
11 package ohos.global.icu.text;
12 
13 import java.io.IOException;
14 import java.io.InvalidObjectException;
15 import java.io.ObjectInputStream;
16 import java.io.ObjectOutputStream;
17 import java.math.BigInteger;
18 import java.text.FieldPosition;
19 import java.text.Format;
20 import java.text.ParseException;
21 import java.text.ParsePosition;
22 import java.util.Collections;
23 import java.util.Locale;
24 import java.util.MissingResourceException;
25 import java.util.Set;
26 
27 import ohos.global.icu.impl.ICUData;
28 import ohos.global.icu.impl.ICUResourceBundle;
29 import ohos.global.icu.number.NumberFormatter;
30 import ohos.global.icu.util.Currency;
31 import ohos.global.icu.util.Currency.CurrencyUsage;
32 import ohos.global.icu.util.CurrencyAmount;
33 import ohos.global.icu.util.ULocale;
34 import ohos.global.icu.util.ULocale.Category;
35 import ohos.global.icu.util.UResourceBundle;
36 
37 /**
38  * <strong>[icu enhancement]</strong> ICU's replacement for {@link java.text.NumberFormat}.&nbsp;Methods, fields, and other functionality specific to ICU are labeled '<strong>[icu]</strong>'.
39  *
40  * <p>
41  * <strong>IMPORTANT:</strong> New users are strongly encouraged to see if
42  * {@link NumberFormatter} fits their use case.  Although not deprecated, this
43  * class, NumberFormat, is only provided for java.text.NumberFormat compatibility.
44  * <hr>
45  *
46  * <code>NumberFormat</code> is the abstract base class for all number
47  * formats. This class provides the interface for formatting and parsing
48  * numbers. <code>NumberFormat</code> also provides methods for determining
49  * which locales have number formats, and what their names are.
50  *
51  * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
52  * Your code can be completely independent of the locale conventions for
53  * decimal points, thousands-separators, or even the particular decimal
54  * digits used, or whether the number format is even decimal.
55  *
56  * <p>
57  * To format a number for the current Locale, use one of the factory
58  * class methods:
59  * <blockquote>
60  * <pre>
61  *  myString = NumberFormat.getInstance().format(myNumber);
62  * </pre>
63  * </blockquote>
64  * If you are formatting multiple numbers, it is
65  * more efficient to get the format and use it multiple times so that
66  * the system doesn't have to fetch the information about the local
67  * language and country conventions multiple times.
68  * <blockquote>
69  * <pre>
70  * NumberFormat nf = NumberFormat.getInstance();
71  * for (int i = 0; i &lt; a.length; ++i) {
72  *     output.println(nf.format(myNumber[i]) + "; ");
73  * }
74  * </pre>
75  * </blockquote>
76  * To format a number for a different Locale, specify it in the
77  * call to <code>getInstance</code>.
78  * <blockquote>
79  * <pre>
80  * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
81  * </pre>
82  * </blockquote>
83  * You can also use a <code>NumberFormat</code> to parse numbers:
84  * <blockquote>
85  * <pre>
86  * myNumber = nf.parse(myString);
87  * </pre>
88  * </blockquote>
89  * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
90  * normal number format. Use <code>getIntegerInstance</code> to get an
91  * integer number format. Use <code>getCurrencyInstance</code> to get the
92  * currency number format. And use <code>getPercentInstance</code> to get a
93  * format for displaying percentages. Some factory methods are found within
94  * subclasses of NumberFormat. With this format, a fraction like
95  * 0.53 is displayed as 53%.
96  *
97  * <p>
98  * Starting from ICU 4.2, you can use getInstance() by passing in a 'style'
99  * as parameter to get the correct instance.
100  * For example,
101  * use getInstance(...NUMBERSTYLE) to get the normal number format,
102  * getInstance(...PERCENTSTYLE) to get a format for displaying percentage,
103  * getInstance(...SCIENTIFICSTYLE) to get a format for displaying scientific number,
104  * getInstance(...INTEGERSTYLE) to get an integer number format,
105  * getInstance(...CURRENCYSTYLE) to get the currency number format,
106  * in which the currency is represented by its symbol, for example, "$3.00".
107  * getInstance(...ISOCURRENCYSTYLE)  to get the currency number format,
108  * in which the currency is represented by its ISO code, for example "USD3.00".
109  * getInstance(...PLURALCURRENCYSTYLE) to get the currency number format,
110  * in which the currency is represented by its full name in plural format,
111  * for example, "3.00 US dollars" or "1.00 US dollar".
112  *
113  *
114  * <p>
115  * You can also control the display of numbers with such methods as
116  * <code>setMinimumFractionDigits</code>.
117  * If you want even more control over the format or parsing,
118  * or want to give your users more control,
119  * you can try casting the <code>NumberFormat</code> you get from the factory methods
120  * to a <code>DecimalFormat</code>. This will work for the vast majority
121  * of locales; just remember to put it in a <code>try</code> block in case you
122  * encounter an unusual one.
123  *
124  * <p>
125  * NumberFormat is designed such that some controls
126  * work for formatting and others work for parsing.  The following is
127  * the detailed description for each these control methods,
128  * <p>
129  * setParseIntegerOnly : only affects parsing, e.g.
130  * if true,  "3456.78" -&gt; 3456 (and leaves the parse position just after '6')
131  * if false, "3456.78" -&gt; 3456.78 (and leaves the parse position just after '8')
132  * This is independent of formatting.  If you want to not show a decimal point
133  * where there might be no digits after the decimal point, use
134  * setDecimalSeparatorAlwaysShown on DecimalFormat.
135  * <p>
136  * You can also use forms of the <code>parse</code> and <code>format</code>
137  * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
138  * allow you to:
139  * <ul>
140  * <li> progressively parse through pieces of a string
141  * <li> align the decimal point and other areas
142  * </ul>
143  * For example, you can align numbers in two ways:
144  * <ol>
145  * <li> If you are using a monospaced font with spacing for alignment,
146  *      you can pass the <code>FieldPosition</code> in your format call, with
147  *      <code>field</code> = <code>INTEGER_FIELD</code>. On output,
148  *      <code>getEndIndex</code> will be set to the offset between the
149  *      last character of the integer and the decimal. Add
150  *      (desiredSpaceCount - getEndIndex) spaces at the front of the string.
151  *
152  * <li> If you are using proportional fonts,
153  *      instead of padding with spaces, measure the width
154  *      of the string in pixels from the start to <code>getEndIndex</code>.
155  *      Then move the pen by
156  *      (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
157  *      It also works where there is no decimal, but possibly additional
158  *      characters at the end, e.g., with parentheses in negative
159  *      numbers: "(12)" for -12.
160  * </ol>
161  *
162  * <h3>Synchronization</h3>
163  * <p>
164  * Number formats are generally not synchronized. It is recommended to create
165  * separate format instances for each thread. If multiple threads access a format
166  * concurrently, it must be synchronized externally.
167  *
168  * <h4>DecimalFormat</h4>
169  * <p>DecimalFormat is the concrete implementation of NumberFormat, and the
170  * NumberFormat API is essentially an abstraction from DecimalFormat's API.
171  * Refer to DecimalFormat for more information about this API.</p>
172  *
173  * see          DecimalFormat
174  * see          java.text.ChoiceFormat
175  * @author       Mark Davis
176  * @author       Helena Shih
177  * @author       Alan Liu
178  */
179 public abstract class NumberFormat extends UFormat {
180 
181     /**
182      * <strong>[icu]</strong> Constant to specify normal number style of format.
183      */
184     public static final int NUMBERSTYLE = 0;
185     /**
186      * <strong>[icu]</strong> Constant to specify general currency style of format. Defaults to
187      * STANDARDCURRENCYSTYLE, using currency symbol, for example "$3.00", with
188      * non-accounting style for negative values (e.g. minus sign).
189      * The specific style may be specified using the -cf- locale key.
190      */
191     public static final int CURRENCYSTYLE = 1;
192     /**
193      * <strong>[icu]</strong> Constant to specify a style of format to display percent.
194      */
195     public static final int PERCENTSTYLE = 2;
196     /**
197      * <strong>[icu]</strong> Constant to specify a style of format to display scientific number.
198      */
199     public static final int SCIENTIFICSTYLE = 3;
200     /**
201      * <strong>[icu]</strong> Constant to specify a integer number style format.
202      */
203     public static final int INTEGERSTYLE = 4;
204     /**
205      * <strong>[icu]</strong> Constant to specify currency style of format which uses currency
206      * ISO code to represent currency, for example: "USD3.00".
207      */
208     public static final int ISOCURRENCYSTYLE = 5;
209     /**
210      * <strong>[icu]</strong> Constant to specify currency style of format which uses currency
211      * long name with plural format to represent currency, for example,
212      * "3.00 US Dollars".
213      */
214     public static final int PLURALCURRENCYSTYLE = 6;
215     /**
216      * <strong>[icu]</strong> Constant to specify currency style of format which uses currency symbol
217      * to represent currency for accounting, for example: "($3.00), instead of
218      * "-$3.00" ({@link #CURRENCYSTYLE}).
219      * Overrides any style specified using -cf- key in locale.
220      */
221     public static final int ACCOUNTINGCURRENCYSTYLE = 7;
222     /**
223      * <strong>[icu]</strong> Constant to specify currency cash style of format which uses currency
224      * ISO code to represent currency, for example: "NT$3" instead of "NT$3.23".
225      */
226     public static final int CASHCURRENCYSTYLE = 8;
227     /**
228      * <strong>[icu]</strong> Constant to specify currency style of format which uses currency symbol
229      * to represent currency, for example "$3.00", using non-accounting style for
230      * negative values (e.g. minus sign).
231      * Overrides any style specified using -cf- key in locale.
232      */
233     public static final int STANDARDCURRENCYSTYLE = 9;
234 
235     /**
236      * Field constant used to construct a FieldPosition object. Signifies that
237      * the position of the integer part of a formatted number should be returned.
238      * @see java.text.FieldPosition
239      */
240     public static final int INTEGER_FIELD = 0;
241 
242     /**
243      * Field constant used to construct a FieldPosition object. Signifies that
244      * the position of the fraction part of a formatted number should be returned.
245      * @see java.text.FieldPosition
246      */
247     public static final int FRACTION_FIELD = 1;
248 
249     /**
250      * Formats a number and appends the resulting text to the given string buffer.
251      * <strong>[icu] Note:</strong> recognizes <code>BigInteger</code>
252      * and <code>BigDecimal</code> objects.
253      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
254      */
255     @Override
format(Object number, StringBuffer toAppendTo, FieldPosition pos)256     public StringBuffer format(Object number,
257                                StringBuffer toAppendTo,
258                                FieldPosition pos) {
259         // NOTE: Number type expansion happens both here
260         // and in DecimalQuantity_DualStorageBCD.java
261         if (number instanceof Long) {
262             return format(((Long)number).longValue(), toAppendTo, pos);
263         } else if (number instanceof BigInteger) {
264             return format((BigInteger) number, toAppendTo, pos);
265         } else if (number instanceof java.math.BigDecimal) {
266             return format((java.math.BigDecimal) number, toAppendTo, pos);
267         } else if (number instanceof ohos.global.icu.math.BigDecimal) {
268             return format((ohos.global.icu.math.BigDecimal) number, toAppendTo, pos);
269         } else if (number instanceof CurrencyAmount) {
270             return format((CurrencyAmount)number, toAppendTo, pos);
271         } else if (number instanceof Number) {
272             return format(((Number)number).doubleValue(), toAppendTo, pos);
273         } else {
274             throw new IllegalArgumentException("Cannot format given Object as a Number");
275         }
276     }
277 
278     /**
279      * Parses text from a string to produce a number.
280      * @param source the String to parse
281      * @param parsePosition the position at which to start the parse
282      * @return the parsed number, or null
283      * @see java.text.NumberFormat#parseObject(String, ParsePosition)
284      */
285     @Override
parseObject(String source, ParsePosition parsePosition)286     public final Object parseObject(String source,
287                                     ParsePosition parsePosition) {
288         return parse(source, parsePosition);
289     }
290 
291     /**
292      * Specialization of format.
293      * @see java.text.Format#format(Object)
294      */
format(double number)295     public final String format(double number) {
296         return format(number,new StringBuffer(),
297                       new FieldPosition(0)).toString();
298     }
299 
300     /**
301      * Specialization of format.
302      * @see java.text.Format#format(Object)
303      */
format(long number)304     public final String format(long number) {
305         StringBuffer buf = new StringBuffer(19);
306         FieldPosition pos = new FieldPosition(0);
307         format(number, buf, pos);
308         return buf.toString();
309     }
310 
311     /**
312      * <strong>[icu]</strong> Convenience method to format a BigInteger.
313      */
format(BigInteger number)314     public final String format(BigInteger number) {
315         return format(number, new StringBuffer(),
316                       new FieldPosition(0)).toString();
317     }
318 
319     /**
320      * Convenience method to format a BigDecimal.
321      */
format(java.math.BigDecimal number)322     public final String format(java.math.BigDecimal number) {
323         return format(number, new StringBuffer(),
324                       new FieldPosition(0)).toString();
325     }
326 
327     /**
328      * <strong>[icu]</strong> Convenience method to format an ICU BigDecimal.
329      */
format(ohos.global.icu.math.BigDecimal number)330     public final String format(ohos.global.icu.math.BigDecimal number) {
331         return format(number, new StringBuffer(),
332                       new FieldPosition(0)).toString();
333     }
334 
335     /**
336      * <strong>[icu]</strong> Convenience method to format a CurrencyAmount.
337      */
format(CurrencyAmount currAmt)338     public final String format(CurrencyAmount currAmt) {
339         return format(currAmt, new StringBuffer(),
340                       new FieldPosition(0)).toString();
341     }
342 
343     /**
344      * Specialization of format.
345      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
346      */
format(double number, StringBuffer toAppendTo, FieldPosition pos)347     public abstract StringBuffer format(double number,
348                                         StringBuffer toAppendTo,
349                                         FieldPosition pos);
350 
351     /**
352      * Specialization of format.
353      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
354      */
format(long number, StringBuffer toAppendTo, FieldPosition pos)355     public abstract StringBuffer format(long number,
356                                         StringBuffer toAppendTo,
357                                         FieldPosition pos);
358     /**
359      * <strong>[icu]</strong> Formats a BigInteger. Specialization of format.
360      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
361      */
format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos)362     public abstract StringBuffer format(BigInteger number,
363                                         StringBuffer toAppendTo,
364                                         FieldPosition pos);
365     /**
366      * <strong>[icu]</strong> Formats a BigDecimal. Specialization of format.
367      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
368      */
format(java.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos)369     public abstract StringBuffer format(java.math.BigDecimal number,
370                                         StringBuffer toAppendTo,
371                                         FieldPosition pos);
372     /**
373      * <strong>[icu]</strong> Formats an ICU BigDecimal. Specialization of format.
374      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
375      */
format(ohos.global.icu.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos)376     public abstract StringBuffer format(ohos.global.icu.math.BigDecimal number,
377                                         StringBuffer toAppendTo,
378                                         FieldPosition pos);
379     /**
380      * <strong>[icu]</strong> Formats a CurrencyAmount. Specialization of format.
381      * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
382      */
format(CurrencyAmount currAmt, StringBuffer toAppendTo, FieldPosition pos)383     public StringBuffer format(CurrencyAmount currAmt,
384                                StringBuffer toAppendTo,
385                                FieldPosition pos) {
386         // Default implementation -- subclasses may override
387         synchronized(this) {
388             Currency save = getCurrency(), curr = currAmt.getCurrency();
389             boolean same = curr.equals(save);
390             if (!same) setCurrency(curr);
391             format(currAmt.getNumber(), toAppendTo, pos);
392             if (!same) setCurrency(save);
393         }
394         return toAppendTo;
395     }
396 
397     /**
398      * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
399      * Long.MAX_VALUE] and with no decimals); otherwise, returns another type,
400      * such as a BigDecimal, BigInteger, or Double. The return type is not
401      * guaranteed other than for the Long case.
402      *
403      * <p>If IntegerOnly is set, will stop at a decimal
404      * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
405      * after the 1).
406      *
407      * <p>Does not throw an exception; if no object can be parsed, index is
408      * unchanged!
409      *
410      * <p>For more detail on parsing, see the "Parsing" header in the class
411      * documentation of {@link DecimalFormat}.
412      *
413      * @see #isParseIntegerOnly
414      * @see DecimalFormat#setParseBigDecimal
415      * @see java.text.Format#parseObject(String, ParsePosition)
416      */
parse(String text, ParsePosition parsePosition)417     public abstract Number parse(String text, ParsePosition parsePosition);
418 
419     /**
420      * Parses text from the beginning of the given string to produce a number.
421      * The method might not use the entire text of the given string.
422      *
423      * @param text A String whose beginning should be parsed.
424      * @return A Number parsed from the string.
425      * @throws ParseException if the beginning of the specified string
426      * cannot be parsed.
427      * @see #format
428      */
429     //Bug 4375399 [Richard/GCL]
parse(String text)430     public Number parse(String text) throws ParseException {
431         ParsePosition parsePosition = new ParsePosition(0);
432         Number result = parse(text, parsePosition);
433         if (parsePosition.getIndex() == 0) {
434             throw new ParseException("Unparseable number: \"" + text + '"',
435                                      parsePosition.getErrorIndex());
436         }
437         return result;
438     }
439 
440     /**
441      * Parses text from the given string as a CurrencyAmount.  Unlike
442      * the parse() method, this method will attempt to parse a generic
443      * currency name, searching for a match of this object's locale's
444      * currency display names, or for a 3-letter ISO currency code.
445      * This method will fail if this format is not a currency format,
446      * that is, if it does not contain the currency pattern symbol
447      * (U+00A4) in its prefix or suffix.
448      *
449      * @param text the text to parse
450      * @param pos input-output position; on input, the position within
451      * text to match; must have 0 &lt;= pos.getIndex() &lt; text.length();
452      * on output, the position after the last matched character. If
453      * the parse fails, the position in unchanged upon output.
454      * @return a CurrencyAmount, or null upon failure
455      */
parseCurrency(CharSequence text, ParsePosition pos)456     public CurrencyAmount parseCurrency(CharSequence text, ParsePosition pos) {
457         ///CLOVER:OFF
458         // Default implementation only -- subclasses should override
459         Number n = parse(text.toString(), pos);
460         return n == null ? null : new CurrencyAmount(n, getEffectiveCurrency());
461         ///CLOVER:ON
462     }
463 
464     /**
465      * Returns true if this format will parse numbers as integers only.
466      * For example in the English locale, with ParseIntegerOnly true, the
467      * string "1234." would be parsed as the integer value 1234 and parsing
468      * would stop at the "." character.  The decimal separator accepted
469      * by the parse operation is locale-dependent and determined by the
470      * subclass.
471      *
472      * @return true if this will parse integers only
473      */
isParseIntegerOnly()474     public boolean isParseIntegerOnly() {
475         return parseIntegerOnly;
476     }
477 
478     /**
479      * Sets whether to ignore the fraction part of a number when parsing
480      * (defaults to false). If a string contains a decimal point, parsing will stop before the decimal
481      * point. Note that determining whether a character is a decimal point depends on the locale.
482      *
483      * <p>For example, in <em>en-US</em>, parsing the string "123.45" will return the number 123 and
484      * parse position 3.
485      *
486      * @param value true if this should parse integers only
487      * @see #isParseIntegerOnly
488      */
setParseIntegerOnly(boolean value)489     public void setParseIntegerOnly(boolean value) {
490         parseIntegerOnly = value;
491     }
492 
493     /**
494      * <strong>[icu]</strong> Sets whether strict parsing is in effect.  When this is true, the string
495      * is required to be a stronger match to the pattern than when lenient parsing is in
496      * effect.  More specifically, the following conditions cause a parse failure relative
497      * to lenient mode (examples use the pattern "#,##0.#"):<ul>
498      * <li>The presence and position of special symbols, including currency, must match the
499      * pattern.<br>
500      * '+123' fails (there is no plus sign in the pattern)</li>
501      * <li>Leading or doubled grouping separators<br>
502      * ',123' and '1,,234" fail</li>
503      * <li>Groups of incorrect length when grouping is used<br>
504      * '1,23' and '1234,567' fail, but '1234' passes</li>
505      * <li>Grouping separators used in numbers followed by exponents<br>
506      * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when
507      * not followed by a number)</li>
508      * </ul>
509      * When strict parsing is off,  all grouping separators are ignored.
510      * This is the default behavior.
511      * @param value True to enable strict parsing.  Default is false.
512      * @see #isParseStrict
513      */
setParseStrict(boolean value)514     public void setParseStrict(boolean value) {
515         parseStrict = value;
516     }
517 
518     /**
519      * <strong>[icu]</strong> Returns whether strict parsing is in effect.
520      * @return true if strict parsing is in effect
521      * @see #setParseStrict
522      */
isParseStrict()523     public boolean isParseStrict() {
524         return parseStrict;
525     }
526 
527     /**
528      * <strong>[icu]</strong> Set a particular DisplayContext value in the formatter,
529      * such as CAPITALIZATION_FOR_STANDALONE.
530      *
531      * @param context The DisplayContext value to set.
532      */
setContext(DisplayContext context)533     public void setContext(DisplayContext context) {
534         if (context.type() == DisplayContext.Type.CAPITALIZATION) {
535             capitalizationSetting = context;
536         }
537     }
538 
539     /**
540      * <strong>[icu]</strong> Get the formatter's DisplayContext value for the specified DisplayContext.Type,
541      * such as CAPITALIZATION.
542      *
543      * @param type the DisplayContext.Type whose value to return
544      * @return the current DisplayContext setting for the specified type
545      */
getContext(DisplayContext.Type type)546     public DisplayContext getContext(DisplayContext.Type type) {
547         return (type == DisplayContext.Type.CAPITALIZATION && capitalizationSetting != null)?
548                 capitalizationSetting: DisplayContext.CAPITALIZATION_NONE;
549     }
550 
551     //============== Locale Stuff =====================
552 
553     /**
554      * <strong>NOTE:</strong> New users are strongly encouraged to use
555      * {@link NumberFormatter} instead of NumberFormat.
556      * <hr>
557      * Returns the default number format for the current default <code>FORMAT</code> locale.
558      * The default format is one of the styles provided by the other
559      * factory methods: getNumberInstance, getIntegerInstance,
560      * getCurrencyInstance or getPercentInstance.
561      * Exactly which one is locale-dependent.
562      * @see Category#FORMAT
563      */
564     //Bug 4408066 [Richard/GCL]
getInstance()565     public final static NumberFormat getInstance() {
566         return getInstance(ULocale.getDefault(Category.FORMAT), NUMBERSTYLE);
567     }
568 
569     /**
570      * <strong>NOTE:</strong> New users are strongly encouraged to use
571      * {@link NumberFormatter} instead of NumberFormat.
572      * <hr>
573      * Returns the default number format for the specified locale.
574      * The default format is one of the styles provided by the other
575      * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
576      * Exactly which one is locale-dependent.
577      */
getInstance(Locale inLocale)578     public static NumberFormat getInstance(Locale inLocale) {
579         return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
580     }
581 
582     /**
583      * <strong>NOTE:</strong> New users are strongly encouraged to use
584      * {@link NumberFormatter} instead of NumberFormat.
585      * <hr>
586      * <strong>[icu]</strong> Returns the default number format for the specified locale.
587      * The default format is one of the styles provided by the other
588      * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
589      * Exactly which one is locale-dependent.
590      */
getInstance(ULocale inLocale)591     public static NumberFormat getInstance(ULocale inLocale) {
592         return getInstance(inLocale, NUMBERSTYLE);
593     }
594 
595     /**
596      * <strong>NOTE:</strong> New users are strongly encouraged to use
597      * {@link NumberFormatter} instead of NumberFormat.
598      * <hr>
599      * <strong>[icu]</strong> Returns a specific style number format for default <code>FORMAT</code> locale.
600      * @param style  number format style
601      * @see Category#FORMAT
602      */
getInstance(int style)603     public final static NumberFormat getInstance(int style) {
604         return getInstance(ULocale.getDefault(Category.FORMAT), style);
605     }
606 
607     /**
608      * <strong>NOTE:</strong> New users are strongly encouraged to use
609      * {@link NumberFormatter} instead of NumberFormat.
610      * <hr>
611      * <strong>[icu]</strong> Returns a specific style number format for a specific locale.
612      * @param inLocale  the specific locale.
613      * @param style     number format style
614      */
getInstance(Locale inLocale, int style)615     public static NumberFormat getInstance(Locale inLocale, int style) {
616         return getInstance(ULocale.forLocale(inLocale), style);
617     }
618 
619 
620     /**
621      * <strong>NOTE:</strong> New users are strongly encouraged to use
622      * {@link NumberFormatter} instead of NumberFormat.
623      * <hr>
624      * Returns a general-purpose number format for the current default <code>FORMAT</code> locale.
625      * @see Category#FORMAT
626      */
getNumberInstance()627     public final static NumberFormat getNumberInstance() {
628         return getInstance(ULocale.getDefault(Category.FORMAT), NUMBERSTYLE);
629     }
630 
631     /**
632      * <strong>NOTE:</strong> New users are strongly encouraged to use
633      * {@link NumberFormatter} instead of NumberFormat.
634      * <hr>
635      * Returns a general-purpose number format for the specified locale.
636      */
getNumberInstance(Locale inLocale)637     public static NumberFormat getNumberInstance(Locale inLocale) {
638         return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
639     }
640 
641     /**
642      * <strong>NOTE:</strong> New users are strongly encouraged to use
643      * {@link NumberFormatter} instead of NumberFormat.
644      * <hr>
645      * <strong>[icu]</strong> Returns a general-purpose number format for the specified locale.
646      */
getNumberInstance(ULocale inLocale)647     public static NumberFormat getNumberInstance(ULocale inLocale) {
648         return getInstance(inLocale, NUMBERSTYLE);
649     }
650 
651     /**
652      * <strong>NOTE:</strong> New users are strongly encouraged to use
653      * {@link NumberFormatter} instead of NumberFormat.
654      * <hr>
655      * Returns an integer number format for the current default <code>FORMAT</code> locale. The
656      * returned number format is configured to round floating point numbers
657      * to the nearest integer using IEEE half-even rounding (see {@link
658      * ohos.global.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
659      * and to parse only the integer part of an input string (see {@link
660      * #isParseIntegerOnly isParseIntegerOnly}).
661      *
662      * @return a number format for integer values
663      * @see Category#FORMAT
664      */
665     //Bug 4408066 [Richard/GCL]
getIntegerInstance()666     public final static NumberFormat getIntegerInstance() {
667         return getInstance(ULocale.getDefault(Category.FORMAT), INTEGERSTYLE);
668     }
669 
670     /**
671      * <strong>NOTE:</strong> New users are strongly encouraged to use
672      * {@link NumberFormatter} instead of NumberFormat.
673      * <hr>
674      * Returns an integer number format for the specified locale. The
675      * returned number format is configured to round floating point numbers
676      * to the nearest integer using IEEE half-even rounding (see {@link
677      * ohos.global.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
678      * and to parse only the integer part of an input string (see {@link
679      * #isParseIntegerOnly isParseIntegerOnly}).
680      *
681      * @param inLocale the locale for which a number format is needed
682      * @return a number format for integer values
683      */
684     //Bug 4408066 [Richard/GCL]
getIntegerInstance(Locale inLocale)685     public static NumberFormat getIntegerInstance(Locale inLocale) {
686         return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE);
687     }
688 
689     /**
690      * <strong>NOTE:</strong> New users are strongly encouraged to use
691      * {@link NumberFormatter} instead of NumberFormat.
692      * <hr>
693      * <strong>[icu]</strong> Returns an integer number format for the specified locale. The
694      * returned number format is configured to round floating point numbers
695      * to the nearest integer using IEEE half-even rounding (see {@link
696      * ohos.global.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
697      * and to parse only the integer part of an input string (see {@link
698      * #isParseIntegerOnly isParseIntegerOnly}).
699      *
700      * @param inLocale the locale for which a number format is needed
701      * @return a number format for integer values
702      */
getIntegerInstance(ULocale inLocale)703     public static NumberFormat getIntegerInstance(ULocale inLocale) {
704         return getInstance(inLocale, INTEGERSTYLE);
705     }
706 
707     /**
708      * <strong>NOTE:</strong> New users are strongly encouraged to use
709      * {@link NumberFormatter} instead of NumberFormat.
710      * <hr>
711      * Returns a currency format for the current default <code>FORMAT</code> locale.
712      * @return a number format for currency
713      * @see Category#FORMAT
714      */
getCurrencyInstance()715     public final static NumberFormat getCurrencyInstance() {
716         return getInstance(ULocale.getDefault(Category.FORMAT), CURRENCYSTYLE);
717     }
718 
719     /**
720      * <strong>NOTE:</strong> New users are strongly encouraged to use
721      * {@link NumberFormatter} instead of NumberFormat.
722      * <hr>
723      * Returns a currency format for the specified locale.
724      * @return a number format for currency
725      */
getCurrencyInstance(Locale inLocale)726     public static NumberFormat getCurrencyInstance(Locale inLocale) {
727         return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE);
728     }
729 
730     /**
731      * <strong>NOTE:</strong> New users are strongly encouraged to use
732      * {@link NumberFormatter} instead of NumberFormat.
733      * <hr>
734      * <strong>[icu]</strong> Returns a currency format for the specified locale.
735      * @return a number format for currency
736      */
getCurrencyInstance(ULocale inLocale)737     public static NumberFormat getCurrencyInstance(ULocale inLocale) {
738         return getInstance(inLocale, CURRENCYSTYLE);
739     }
740 
741     /**
742      * <strong>NOTE:</strong> New users are strongly encouraged to use
743      * {@link NumberFormatter} instead of NumberFormat.
744      * <hr>
745      * Returns a percentage format for the current default <code>FORMAT</code> locale.
746      * @return a number format for percents
747      * @see Category#FORMAT
748      */
getPercentInstance()749     public final static NumberFormat getPercentInstance() {
750         return getInstance(ULocale.getDefault(Category.FORMAT), PERCENTSTYLE);
751     }
752 
753     /**
754      * <strong>NOTE:</strong> New users are strongly encouraged to use
755      * {@link NumberFormatter} instead of NumberFormat.
756      * <hr>
757      * Returns a percentage format for the specified locale.
758      * @return a number format for percents
759      */
getPercentInstance(Locale inLocale)760     public static NumberFormat getPercentInstance(Locale inLocale) {
761         return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE);
762     }
763 
764     /**
765      * <strong>NOTE:</strong> New users are strongly encouraged to use
766      * {@link NumberFormatter} instead of NumberFormat.
767      * <hr>
768      * <strong>[icu]</strong> Returns a percentage format for the specified locale.
769      * @return a number format for percents
770      */
getPercentInstance(ULocale inLocale)771     public static NumberFormat getPercentInstance(ULocale inLocale) {
772         return getInstance(inLocale, PERCENTSTYLE);
773     }
774 
775     /**
776      * <strong>NOTE:</strong> New users are strongly encouraged to use
777      * {@link NumberFormatter} instead of NumberFormat.
778      * <hr>
779      * <strong>[icu]</strong> Returns a scientific format for the current default <code>FORMAT</code> locale.
780      * @return a scientific number format
781      * @see Category#FORMAT
782      */
getScientificInstance()783     public final static NumberFormat getScientificInstance() {
784         return getInstance(ULocale.getDefault(Category.FORMAT), SCIENTIFICSTYLE);
785     }
786 
787     /**
788      * <strong>NOTE:</strong> New users are strongly encouraged to use
789      * {@link NumberFormatter} instead of NumberFormat.
790      * <hr>
791      * <strong>[icu]</strong> Returns a scientific format for the specified locale.
792      * @return a scientific number format
793      */
getScientificInstance(Locale inLocale)794     public static NumberFormat getScientificInstance(Locale inLocale) {
795         return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE);
796     }
797 
798     /**
799      * <strong>NOTE:</strong> New users are strongly encouraged to use
800      * {@link NumberFormatter} instead of NumberFormat.
801      * <hr>
802      * <strong>[icu]</strong> Returns a scientific format for the specified locale.
803      * @return a scientific number format
804      */
getScientificInstance(ULocale inLocale)805     public static NumberFormat getScientificInstance(ULocale inLocale) {
806         return getInstance(inLocale, SCIENTIFICSTYLE);
807     }
808 
809     // ===== Factory stuff =====
810     /**
811      * A NumberFormatFactory is used to register new number formats.  The factory
812      * should be able to create any of the predefined formats for each locale it
813      * supports.  When registered, the locales it supports extend or override the
814      * locales already supported by ICU.
815      *
816      * <p><b>Note:</b> as of ICU4J 3.2, the default API for NumberFormatFactory uses
817      * ULocale instead of Locale.  Instead of overriding createFormat(Locale, int),
818      * new implementations should override createFactory(ULocale, int).  Note that
819      * one of these two methods <b>MUST</b> be overridden or else an infinite
820      * loop will occur.
821      *
822      * @hide exposed on OHOS
823      * @hide unsupported on OHOS
824      */
825     public static abstract class NumberFormatFactory {
826         /**
827          * Value passed to format requesting a default number format.
828          */
829         public static final int FORMAT_NUMBER = NUMBERSTYLE;
830 
831         /**
832          * Value passed to format requesting a currency format.
833          */
834         public static final int FORMAT_CURRENCY = CURRENCYSTYLE;
835 
836         /**
837          * Value passed to format requesting a percent format.
838          */
839         public static final int FORMAT_PERCENT = PERCENTSTYLE;
840 
841         /**
842          * Value passed to format requesting a scientific format.
843          */
844         public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE;
845 
846         /**
847          * Value passed to format requesting an integer format.
848          */
849         public static final int FORMAT_INTEGER = INTEGERSTYLE;
850 
851         /**
852          * Returns true if this factory is visible.  Default is true.
853          * If not visible, the locales supported by this factory will not
854          * be listed by getAvailableLocales.  This value must not change.
855          * @return true if the factory is visible.
856          */
visible()857         public boolean visible() {
858             return true;
859         }
860 
861         /**
862          * Returns an immutable collection of the locale names directly
863          * supported by this factory.
864          * @return the supported locale names.
865          */
getSupportedLocaleNames()866          public abstract Set<String> getSupportedLocaleNames();
867 
868         /**
869          * Returns a number format of the appropriate type.  If the locale
870          * is not supported, return null.  If the locale is supported, but
871          * the type is not provided by this service, return null.  Otherwise
872          * return an appropriate instance of NumberFormat.
873          * <b>Note:</b> as of ICU4J 3.2, implementations should override
874          * this method instead of createFormat(Locale, int).
875          * @param loc the locale for which to create the format
876          * @param formatType the type of format
877          * @return the NumberFormat, or null.
878          */
createFormat(ULocale loc, int formatType)879         public NumberFormat createFormat(ULocale loc, int formatType) {
880             return createFormat(loc.toLocale(), formatType);
881         }
882 
883         /**
884          * Returns a number format of the appropriate type.  If the locale
885          * is not supported, return null.  If the locale is supported, but
886          * the type is not provided by this service, return null.  Otherwise
887          * return an appropriate instance of NumberFormat.
888          * <b>Note:</b> as of ICU4J 3.2, createFormat(ULocale, int) should be
889          * overridden instead of this method.  This method is no longer
890          * abstract and delegates to that method.
891          * @param loc the locale for which to create the format
892          * @param formatType the type of format
893          * @return the NumberFormat, or null.
894          */
createFormat(Locale loc, int formatType)895         public NumberFormat createFormat(Locale loc, int formatType) {
896             return createFormat(ULocale.forLocale(loc), formatType);
897         }
898 
899         /**
900          */
NumberFormatFactory()901         protected NumberFormatFactory() {
902         }
903     }
904 
905     /**
906      * A NumberFormatFactory that supports a single locale.  It can be visible or invisible.
907      * @hide exposed on OHOS
908      * @hide unsupported on OHOS
909      */
910     public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory {
911         final Set<String> localeNames;
912         final boolean visible;
913 
914         /**
915          * Constructs a SimpleNumberFormatFactory with the given locale.
916          */
SimpleNumberFormatFactory(Locale locale)917         public SimpleNumberFormatFactory(Locale locale) {
918             this(locale, true);
919         }
920 
921         /**
922          * Constructs a SimpleNumberFormatFactory with the given locale and the
923          * visibility.
924          */
SimpleNumberFormatFactory(Locale locale, boolean visible)925         public SimpleNumberFormatFactory(Locale locale, boolean visible) {
926             localeNames = Collections.singleton(ULocale.forLocale(locale).getBaseName());
927             this.visible = visible;
928         }
929 
930         /**
931          * Constructs a SimpleNumberFormatFactory with the given locale.
932          */
SimpleNumberFormatFactory(ULocale locale)933         public SimpleNumberFormatFactory(ULocale locale) {
934             this(locale, true);
935         }
936 
937         /**
938          * Constructs a SimpleNumberFormatFactory with the given locale and the
939          * visibility.
940          */
SimpleNumberFormatFactory(ULocale locale, boolean visible)941         public SimpleNumberFormatFactory(ULocale locale, boolean visible) {
942             localeNames = Collections.singleton(locale.getBaseName());
943             this.visible = visible;
944         }
945 
946         /**
947          * {@inheritDoc}
948          */
949         @Override
visible()950         public final boolean visible() {
951             return visible;
952         }
953 
954         /**
955          * {@inheritDoc}
956          */
957         @Override
getSupportedLocaleNames()958         public final Set<String> getSupportedLocaleNames() {
959             return localeNames;
960         }
961     }
962 
963     // shim so we can build without service code
964     static abstract class NumberFormatShim {
getAvailableLocales()965         abstract Locale[] getAvailableLocales();
getAvailableULocales()966         abstract ULocale[] getAvailableULocales();
registerFactory(NumberFormatFactory f)967         abstract Object registerFactory(NumberFormatFactory f);
unregister(Object k)968         abstract boolean unregister(Object k);
createInstance(ULocale l, int k)969         abstract NumberFormat createInstance(ULocale l, int k);
970     }
971 
972     private static NumberFormatShim shim;
getShim()973     private static NumberFormatShim getShim() {
974         // Note: this instantiation is safe on loose-memory-model configurations
975         // despite lack of synchronization, since the shim instance has no state--
976         // it's all in the class init.  The worst problem is we might instantiate
977         // two shim instances, but they'll share the same state so that's ok.
978         if (shim == null) {
979             try {
980                 Class<?> cls = Class.forName("ohos.global.icu.text.NumberFormatServiceShim");
981                 shim = (NumberFormatShim)cls.newInstance();
982             }
983             ///CLOVER:OFF
984             catch (MissingResourceException e){
985                 throw e;
986             }
987             catch (Exception e) {
988                // e.printStackTrace();
989                 throw new RuntimeException(e.getMessage());
990             }
991             ///CLOVER:ON
992         }
993         return shim;
994     }
995 
996     /**
997      * Returns the list of Locales for which NumberFormats are available.
998      * @return the available locales
999      */
getAvailableLocales()1000     public static Locale[] getAvailableLocales() {
1001         if (shim == null) {
1002             return ICUResourceBundle.getAvailableLocales();
1003         }
1004         return getShim().getAvailableLocales();
1005     }
1006 
1007     /**
1008      * <strong>[icu]</strong> Returns the list of Locales for which NumberFormats are available.
1009      * @return the available locales
1010      * @hide draft / provisional / internal are hidden on OHOS
1011      */
getAvailableULocales()1012     public static ULocale[] getAvailableULocales() {
1013         if (shim == null) {
1014             return ICUResourceBundle.getAvailableULocales();
1015         }
1016         return getShim().getAvailableULocales();
1017     }
1018 
1019     /**
1020      * <strong>[icu]</strong> Registers a new NumberFormatFactory.  The factory is adopted by
1021      * the service and must not be modified.  The returned object is a
1022      * key that can be used to unregister this factory.
1023      *
1024      * <p>Because ICU may choose to cache NumberFormat objects internally, this must
1025      * be called at application startup, prior to any calls to
1026      * NumberFormat.getInstance to avoid undefined behavior.
1027      *
1028      * @param factory the factory to register
1029      * @return a key with which to unregister the factory
1030      * @hide unsupported on OHOS
1031      */
registerFactory(NumberFormatFactory factory)1032     public static Object registerFactory(NumberFormatFactory factory) {
1033         if (factory == null) {
1034             throw new IllegalArgumentException("factory must not be null");
1035         }
1036         return getShim().registerFactory(factory);
1037     }
1038 
1039     /**
1040      * <strong>[icu]</strong> Unregisters the factory or instance associated with this key (obtained from
1041      * registerInstance or registerFactory).
1042      * @param registryKey a key obtained from registerFactory
1043      * @return true if the object was successfully unregistered
1044      * @hide unsupported on OHOS
1045      */
unregister(Object registryKey)1046     public static boolean unregister(Object registryKey) {
1047         if (registryKey == null) {
1048             throw new IllegalArgumentException("registryKey must not be null");
1049         }
1050 
1051         if (shim == null) {
1052             return false;
1053         }
1054 
1055         return shim.unregister(registryKey);
1056     }
1057 
1058     // ===== End of factory stuff =====
1059 
1060     /**
1061      * {@inheritDoc}
1062      */
1063     @Override
hashCode()1064     public int hashCode() {
1065         return maximumIntegerDigits * 37 + maxFractionDigits;
1066         // just enough fields for a reasonable distribution
1067     }
1068 
1069     /**
1070      * Overrides equals.
1071      * Two NumberFormats are equal they are of the same class
1072      * and the user-specified values for settings
1073      * (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc.)
1074      * are equal.
1075      * @param obj the object to compare against
1076      * @return true if the object is equal to this.
1077      */
1078     @Override
equals(Object obj)1079     public boolean equals(Object obj) {
1080         if (obj == null) return false;
1081         if (this == obj)
1082             return true;
1083         if (getClass() != obj.getClass())
1084             return false;
1085         NumberFormat other = (NumberFormat) obj;
1086         return maximumIntegerDigits == other.maximumIntegerDigits
1087             && minimumIntegerDigits == other.minimumIntegerDigits
1088             && maximumFractionDigits == other.maximumFractionDigits
1089             && minimumFractionDigits == other.minimumFractionDigits
1090             && groupingUsed == other.groupingUsed
1091             && parseIntegerOnly == other.parseIntegerOnly
1092             && parseStrict == other.parseStrict
1093             && capitalizationSetting == other.capitalizationSetting;
1094     }
1095 
1096     /**
1097      * Overrides clone.
1098      */
1099     @Override
clone()1100     public Object clone() {
1101         NumberFormat other = (NumberFormat) super.clone();
1102         return other;
1103     }
1104 
1105     /**
1106      * Returns true if grouping is used in this format. For example, in the
1107      * en_US locale, with grouping on, the number 1234567 will be formatted
1108      * as "1,234,567". The grouping separator as well as the size of each group
1109      * is locale-dependent and is determined by subclasses of NumberFormat.
1110      * Grouping affects both parsing and formatting.
1111      * @return true if grouping is used
1112      * @see #setGroupingUsed
1113      */
isGroupingUsed()1114     public boolean isGroupingUsed() {
1115         return groupingUsed;
1116     }
1117 
1118     /**
1119      * Sets whether or not grouping will be used in this format.  Grouping
1120      * affects both parsing and formatting.
1121      * @see #isGroupingUsed
1122      * @param newValue true to use grouping.
1123      */
setGroupingUsed(boolean newValue)1124     public void setGroupingUsed(boolean newValue) {
1125         groupingUsed = newValue;
1126     }
1127 
1128     /**
1129      * Returns the maximum number of digits allowed in the integer portion of a
1130      * number.  The default value is 40, which subclasses can override.
1131      *
1132      * When formatting, if the number of digits exceeds this value, the highest-
1133      * significance digits are truncated until the limit is reached, in accordance
1134      * with UTS#35.
1135      *
1136      * This setting has no effect on parsing.
1137      *
1138      * @return the maximum number of integer digits
1139      * @see #setMaximumIntegerDigits
1140      */
getMaximumIntegerDigits()1141     public int getMaximumIntegerDigits() {
1142         return maximumIntegerDigits;
1143     }
1144 
1145     /**
1146      * Sets the maximum number of digits allowed in the integer portion of a
1147      * number. This must be &gt;= minimumIntegerDigits.  If the
1148      * new value for maximumIntegerDigits is less than the current value
1149      * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
1150      * the new value.
1151      * @param newValue the maximum number of integer digits to be shown; if
1152      * less than zero, then zero is used.  Subclasses might enforce an
1153      * upper limit to this value appropriate to the numeric type being formatted.
1154      * @see #getMaximumIntegerDigits
1155      */
setMaximumIntegerDigits(int newValue)1156     public void setMaximumIntegerDigits(int newValue) {
1157         maximumIntegerDigits = Math.max(0,newValue);
1158         if (minimumIntegerDigits > maximumIntegerDigits)
1159             minimumIntegerDigits = maximumIntegerDigits;
1160     }
1161 
1162     /**
1163      * Returns the minimum number of digits allowed in the integer portion of a
1164      * number.  The default value is 1, which subclasses can override.
1165      * When formatting, if this value is not reached, numbers are padded on the
1166      * left with the locale-specific '0' character to ensure at least this
1167      * number of integer digits.  When parsing, this has no effect.
1168      * @return the minimum number of integer digits
1169      * @see #setMinimumIntegerDigits
1170      */
getMinimumIntegerDigits()1171     public int getMinimumIntegerDigits() {
1172         return minimumIntegerDigits;
1173     }
1174 
1175     /**
1176      * Sets the minimum number of digits allowed in the integer portion of a
1177      * number.  This must be &lt;= maximumIntegerDigits.  If the
1178      * new value for minimumIntegerDigits is more than the current value
1179      * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
1180      * the new value.
1181      * @param newValue the minimum number of integer digits to be shown; if
1182      * less than zero, then zero is used. Subclasses might enforce an
1183      * upper limit to this value appropriate to the numeric type being formatted.
1184      * @see #getMinimumIntegerDigits
1185      */
setMinimumIntegerDigits(int newValue)1186     public void setMinimumIntegerDigits(int newValue) {
1187         minimumIntegerDigits = Math.max(0,newValue);
1188         if (minimumIntegerDigits > maximumIntegerDigits)
1189             maximumIntegerDigits = minimumIntegerDigits;
1190     }
1191 
1192     /**
1193      * Returns the maximum number of digits allowed in the fraction
1194      * portion of a number.  The default value is 3, which subclasses
1195      * can override.  When formatting, the exact behavior when this
1196      * value is exceeded is subclass-specific.  When parsing, this has
1197      * no effect.
1198      * @return the maximum number of fraction digits
1199      * @see #setMaximumFractionDigits
1200      */
getMaximumFractionDigits()1201     public int getMaximumFractionDigits() {
1202         return maximumFractionDigits;
1203     }
1204 
1205     /**
1206      * Sets the maximum number of digits allowed in the fraction portion of a
1207      * number. This must be &gt;= minimumFractionDigits.  If the
1208      * new value for maximumFractionDigits is less than the current value
1209      * of minimumFractionDigits, then minimumFractionDigits will also be set to
1210      * the new value.
1211      * @param newValue the maximum number of fraction digits to be shown; if
1212      * less than zero, then zero is used. The concrete subclass may enforce an
1213      * upper limit to this value appropriate to the numeric type being formatted.
1214      * @see #getMaximumFractionDigits
1215      */
setMaximumFractionDigits(int newValue)1216     public void setMaximumFractionDigits(int newValue) {
1217         maximumFractionDigits = Math.max(0,newValue);
1218         if (maximumFractionDigits < minimumFractionDigits)
1219             minimumFractionDigits = maximumFractionDigits;
1220     }
1221 
1222     /**
1223      * Returns the minimum number of digits allowed in the fraction portion of a
1224      * number.  The default value is 0, which subclasses can override.
1225      * When formatting, if this value is not reached, numbers are padded on
1226      * the right with the locale-specific '0' character to ensure at least
1227      * this number of fraction digits.  When parsing, this has no effect.
1228      * @return the minimum number of fraction digits
1229      * @see #setMinimumFractionDigits
1230      */
getMinimumFractionDigits()1231     public int getMinimumFractionDigits() {
1232         return minimumFractionDigits;
1233     }
1234 
1235     /**
1236      * Sets the minimum number of digits allowed in the fraction portion of a
1237      * number.  This must be &lt;= maximumFractionDigits.  If the
1238      * new value for minimumFractionDigits exceeds the current value
1239      * of maximumFractionDigits, then maximumFractionDigits will also be set to
1240      * the new value.
1241      * @param newValue the minimum number of fraction digits to be shown; if
1242      * less than zero, then zero is used.  Subclasses might enforce an
1243      * upper limit to this value appropriate to the numeric type being formatted.
1244      * @see #getMinimumFractionDigits
1245      */
setMinimumFractionDigits(int newValue)1246     public void setMinimumFractionDigits(int newValue) {
1247         minimumFractionDigits = Math.max(0,newValue);
1248         if (maximumFractionDigits < minimumFractionDigits)
1249             maximumFractionDigits = minimumFractionDigits;
1250     }
1251 
1252     /**
1253      * Sets the <tt>Currency</tt> object used to display currency
1254      * amounts.  This takes effect immediately, if this format is a
1255      * currency format.  If this format is not a currency format, then
1256      * the currency object is used if and when this object becomes a
1257      * currency format.
1258      * @param theCurrency new currency object to use.  May be null for
1259      * some subclasses.
1260      */
setCurrency(Currency theCurrency)1261     public void setCurrency(Currency theCurrency) {
1262         currency = theCurrency;
1263     }
1264 
1265     /**
1266      * Returns the <tt>Currency</tt> object used to display currency
1267      * amounts.  This may be null.
1268      */
getCurrency()1269     public Currency getCurrency() {
1270         return currency;
1271     }
1272 
1273     /**
1274      * Returns the currency in effect for this formatter.  Subclasses
1275      * should override this method as needed.  Unlike getCurrency(),
1276      * this method should never return null.
1277      * @return a non-null Currency
1278      * @deprecated This API is ICU internal only.
1279      * @hide deprecated on icu4j-org
1280      * @hide draft / provisional / internal are hidden on OHOS
1281      */
1282     @Deprecated
getEffectiveCurrency()1283     protected Currency getEffectiveCurrency() {
1284         Currency c = getCurrency();
1285         if (c == null) {
1286             ULocale uloc = getLocale(ULocale.VALID_LOCALE);
1287             if (uloc == null) {
1288                 uloc = ULocale.getDefault(Category.FORMAT);
1289             }
1290             c = Currency.getInstance(uloc);
1291         }
1292         return c;
1293     }
1294 
1295     /**
1296      * Returns the rounding mode used in this NumberFormat.  The default implementation of
1297      * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
1298      * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code>
1299      * and <code>BigDecimal.ROUND_UNNECESSARY</code>.
1300      * @see #setRoundingMode(int)
1301      */
getRoundingMode()1302     public int getRoundingMode() {
1303         throw new UnsupportedOperationException(
1304             "getRoundingMode must be implemented by the subclass implementation.");
1305     }
1306 
1307     /**
1308      * Set the rounding mode used in this NumberFormat.  The default implementation of
1309      * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
1310      * @param roundingMode A rounding mode, between
1311      * <code>BigDecimal.ROUND_UP</code> and
1312      * <code>BigDecimal.ROUND_UNNECESSARY</code>.
1313      * @see #getRoundingMode()
1314      */
setRoundingMode(int roundingMode)1315     public void setRoundingMode(int roundingMode) {
1316         throw new UnsupportedOperationException(
1317             "setRoundingMode must be implemented by the subclass implementation.");
1318     }
1319 
1320 
1321     /**
1322      * <strong>NOTE:</strong> New users are strongly encouraged to use
1323      * {@link NumberFormatter} instead of NumberFormat.
1324      * <hr>
1325      * Returns a specific style number format for a specific locale.
1326      * @param desiredLocale  the specific locale.
1327      * @param choice         number format style
1328      * @throws IllegalArgumentException  if choice is not one of
1329      *                                   NUMBERSTYLE, CURRENCYSTYLE,
1330      *                                   PERCENTSTYLE, SCIENTIFICSTYLE,
1331      *                                   INTEGERSTYLE, ISOCURRENCYSTYLE,
1332      *                                   PLURALCURRENCYSTYLE, ACCOUNTINGCURRENCYSTYLE.
1333      *                                   CASHCURRENCYSTYLE, STANDARDCURRENCYSTYLE.
1334      */
getInstance(ULocale desiredLocale, int choice)1335     public static NumberFormat getInstance(ULocale desiredLocale, int choice) {
1336         if (choice < NUMBERSTYLE || choice > STANDARDCURRENCYSTYLE) {
1337             throw new IllegalArgumentException(
1338                 "choice should be from NUMBERSTYLE to STANDARDCURRENCYSTYLE");
1339         }
1340 //          if (shim == null) {
1341 //              return createInstance(desiredLocale, choice);
1342 //          } else {
1343 //              // TODO: shims must call setLocale() on object they create
1344 //              return getShim().createInstance(desiredLocale, choice);
1345 //          }
1346         return getShim().createInstance(desiredLocale, choice);
1347     }
1348 
1349     // =======================privates===============================
1350     // Hook for service
createInstance(ULocale desiredLocale, int choice)1351     static NumberFormat createInstance(ULocale desiredLocale, int choice) {
1352         // If the choice is PLURALCURRENCYSTYLE, the pattern is not a single
1353         // pattern, it is a pattern set, so we do not need to get them here.
1354         // If the choice is ISOCURRENCYSTYLE, the pattern is the currrency
1355         // pattern in the locale but by replacing the single currency sign
1356         // with double currency sign.
1357         String pattern = getPattern(desiredLocale, choice);
1358         DecimalFormatSymbols symbols = new DecimalFormatSymbols(desiredLocale);
1359 
1360         // Here we assume that the locale passed in is in the canonical
1361         // form, e.g: pt_PT_@currency=PTE
1362         // For currency plural format, the pattern is get from
1363         // the locale (from CurrencyUnitPatterns) without override.
1364         if (choice == CURRENCYSTYLE || choice == ISOCURRENCYSTYLE || choice == ACCOUNTINGCURRENCYSTYLE
1365                 || choice == CASHCURRENCYSTYLE || choice == STANDARDCURRENCYSTYLE) {
1366             String temp = symbols.getCurrencyPattern();
1367             if(temp!=null){
1368                 pattern = temp;
1369             }
1370         }
1371 
1372         // replace single currency sign in the pattern with double currency sign
1373         // if the choice is ISOCURRENCYSTYLE.
1374         if (choice == ISOCURRENCYSTYLE) {
1375             pattern = pattern.replace("\u00A4", doubleCurrencyStr);
1376         }
1377 
1378         // Get the numbering system
1379         NumberingSystem ns = NumberingSystem.getInstance(desiredLocale);
1380         if ( ns == null ) {
1381             return null;
1382         }
1383 
1384         NumberFormat format;
1385 
1386         if ( ns != null && ns.isAlgorithmic()) {
1387             String nsDesc;
1388             String nsRuleSetGroup;
1389             String nsRuleSetName;
1390             ULocale nsLoc;
1391             int desiredRulesType = RuleBasedNumberFormat.NUMBERING_SYSTEM;
1392 
1393             nsDesc = ns.getDescription();
1394             int firstSlash = nsDesc.indexOf("/");
1395             int lastSlash = nsDesc.lastIndexOf("/");
1396 
1397             if ( lastSlash > firstSlash ) {
1398                String nsLocID = nsDesc.substring(0,firstSlash);
1399                nsRuleSetGroup = nsDesc.substring(firstSlash+1,lastSlash);
1400                nsRuleSetName = nsDesc.substring(lastSlash+1);
1401 
1402                nsLoc = new ULocale(nsLocID);
1403                if ( nsRuleSetGroup.equals("SpelloutRules")) {
1404                    desiredRulesType = RuleBasedNumberFormat.SPELLOUT;
1405                }
1406             } else {
1407                 nsLoc = desiredLocale;
1408                 nsRuleSetName = nsDesc;
1409             }
1410 
1411             RuleBasedNumberFormat r = new RuleBasedNumberFormat(nsLoc,desiredRulesType);
1412             r.setDefaultRuleSet(nsRuleSetName);
1413             format = r;
1414         } else {
1415             DecimalFormat f = new DecimalFormat(pattern, symbols, choice);
1416             // System.out.println("loc: " + desiredLocale + " choice: " + choice + " pat: " + pattern + " sym: " + symbols + " result: " + format);
1417 
1418             /*Bug 4408066
1419              Add codes for the new method getIntegerInstance() [Richard/GCL]
1420             */
1421             // TODO: revisit this -- this is almost certainly not the way we want
1422             // to do this.  aliu 1/6/2004
1423             if (choice == INTEGERSTYLE) {
1424                 f.setMaximumFractionDigits(0);
1425                 f.setDecimalSeparatorAlwaysShown(false);
1426                 f.setParseIntegerOnly(true);
1427             }
1428             if (choice == CASHCURRENCYSTYLE) {
1429                 f.setCurrencyUsage(CurrencyUsage.CASH);
1430             }
1431             if (choice == PLURALCURRENCYSTYLE) {
1432                 f.setCurrencyPluralInfo(CurrencyPluralInfo.getInstance(desiredLocale));
1433             }
1434             format = f;
1435        }
1436         // TODO: the actual locale of the *pattern* may differ from that
1437         // for the *symbols*.  For now, we use the data for the symbols.
1438         // Revisit this.
1439         ULocale valid = symbols.getLocale(ULocale.VALID_LOCALE);
1440         ULocale actual = symbols.getLocale(ULocale.ACTUAL_LOCALE);
1441         format.setLocale(valid, actual);
1442 
1443         return format;
1444     }
1445 
1446     /**
1447      * Returns the pattern for the provided locale and choice.
1448      * @param forLocale the locale of the data.
1449      * @param choice the pattern format.
1450      * @return the pattern
1451      * @deprecated ICU 3.4 subclassers should override getPattern(ULocale, int) instead of this method.
1452      * @hide deprecated on icu4j-org
1453      */
1454     @Deprecated
getPattern(Locale forLocale, int choice)1455     protected static String getPattern(Locale forLocale, int choice) {
1456         return getPattern(ULocale.forLocale(forLocale), choice);
1457     }
1458 
1459     /**
1460      * Returns the pattern for the provided locale and choice.
1461      * @param forLocale the locale of the data.
1462      * @param choice the pattern format.
1463      * @return the pattern
1464      */
getPattern(ULocale forLocale, int choice)1465     protected static String getPattern(ULocale forLocale, int choice) {
1466         return getPatternForStyle(forLocale, choice);
1467     }
1468 
1469     /**
1470      * Returns the pattern for the provided locale and choice.
1471      * @param forLocale the locale of the data.
1472      * @param choice the pattern format.
1473      * @return the pattern
1474      * @deprecated This API is ICU internal only.
1475      * @hide draft / provisional / internal are hidden on OHOS
1476      */
1477     @Deprecated
getPatternForStyle(ULocale forLocale, int choice)1478     public static String getPatternForStyle(ULocale forLocale, int choice) {
1479         NumberingSystem ns = NumberingSystem.getInstance(forLocale);
1480         String nsName = ns.getName();
1481         return getPatternForStyleAndNumberingSystem(forLocale, nsName, choice);
1482     }
1483 
1484     /**
1485      * Returns the pattern for the provided locale, numbering system, and choice.
1486      * @param forLocale the locale of the data.
1487      * @param nsName The name of the numbering system, like "latn".
1488      * @param choice the pattern format.
1489      * @return the pattern
1490      * @deprecated This API is ICU internal only.
1491      * @hide draft / provisional / internal are hidden on OHOS
1492      */
1493     @Deprecated
getPatternForStyleAndNumberingSystem(ULocale forLocale, String nsName, int choice)1494     public static String getPatternForStyleAndNumberingSystem(ULocale forLocale, String nsName, int choice) {
1495         /* for ISOCURRENCYSTYLE and PLURALCURRENCYSTYLE,
1496          * the pattern is the same as the pattern of CURRENCYSTYLE
1497          * but by replacing the single currency sign with
1498          * double currency sign or triple currency sign.
1499          */
1500         String patternKey = null;
1501         switch (choice) {
1502         case NUMBERSTYLE:
1503         case INTEGERSTYLE:
1504         case PLURALCURRENCYSTYLE:
1505             patternKey = "decimalFormat";
1506             break;
1507         case CURRENCYSTYLE:
1508             String cfKeyValue = forLocale.getKeywordValue("cf");
1509             patternKey = (cfKeyValue != null && cfKeyValue.equals("account")) ?
1510                     "accountingFormat" : "currencyFormat";
1511             break;
1512         case CASHCURRENCYSTYLE:
1513         case ISOCURRENCYSTYLE:
1514         case STANDARDCURRENCYSTYLE:
1515             patternKey = "currencyFormat";
1516             break;
1517         case PERCENTSTYLE:
1518             patternKey = "percentFormat";
1519             break;
1520         case SCIENTIFICSTYLE:
1521             patternKey = "scientificFormat";
1522             break;
1523         case ACCOUNTINGCURRENCYSTYLE:
1524             patternKey = "accountingFormat";
1525             break;
1526         default:
1527             assert false;
1528             patternKey = "decimalFormat";
1529             break;
1530         }
1531 
1532         ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
1533         getBundleInstance(ICUData.ICU_BASE_NAME, forLocale);
1534 
1535         String result = rb.findStringWithFallback(
1536                     "NumberElements/" + nsName + "/patterns/" + patternKey);
1537         if (result == null) {
1538             result = rb.getStringWithFallback("NumberElements/latn/patterns/" + patternKey);
1539         }
1540 
1541         return result;
1542     }
1543 
1544     /**
1545      * First, read in the default serializable data.
1546      *
1547      * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
1548      * the stream was written by JDK 1.1,
1549      * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1550      * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
1551      * since the <code>int</code> fields were not present in JDK 1.1.
1552      * Finally, set serialVersionOnStream back to the maximum allowed value so that
1553      * default serialization will work properly if this object is streamed out again.
1554      */
readObject(ObjectInputStream stream)1555     private void readObject(ObjectInputStream stream)
1556          throws IOException, ClassNotFoundException
1557     {
1558         stream.defaultReadObject();
1559         ///CLOVER:OFF
1560         // we don't have serialization data for this format
1561         if (serialVersionOnStream < 1) {
1562             // Didn't have additional int fields, reassign to use them.
1563             maximumIntegerDigits = maxIntegerDigits;
1564             minimumIntegerDigits = minIntegerDigits;
1565             maximumFractionDigits = maxFractionDigits;
1566             minimumFractionDigits = minFractionDigits;
1567         }
1568         if (serialVersionOnStream < 2) {
1569             // Didn't have capitalizationSetting, set it to default
1570             capitalizationSetting = DisplayContext.CAPITALIZATION_NONE;
1571         }
1572         ///CLOVER:ON
1573         /*Bug 4185761
1574           Validate the min and max fields [Richard/GCL]
1575         */
1576         if (minimumIntegerDigits > maximumIntegerDigits ||
1577             minimumFractionDigits > maximumFractionDigits ||
1578             minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
1579             throw new InvalidObjectException("Digit count range invalid");
1580         }
1581         serialVersionOnStream = currentSerialVersion;
1582     }
1583 
1584     /**
1585      * Write out the default serializable data, after first setting
1586      * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
1587      * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1588      * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
1589      * with the JDK 1.1 version of the stream format.
1590      */
writeObject(ObjectOutputStream stream)1591     private void writeObject(ObjectOutputStream stream)
1592          throws IOException
1593     {
1594         maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1595             (byte)maximumIntegerDigits;
1596         minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1597             (byte)minimumIntegerDigits;
1598         maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1599             (byte)maximumFractionDigits;
1600         minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
1601             (byte)minimumFractionDigits;
1602         stream.defaultWriteObject();
1603     }
1604 
1605 // Unused -- Alan 2003-05
1606 //    /**
1607 //     * Cache to hold the NumberPatterns of a Locale.
1608 //     */
1609 //    private static final Hashtable cachedLocaleData = new Hashtable(3);
1610 
1611       private static final char[] doubleCurrencySign = {0xA4, 0xA4};
1612       private static final String doubleCurrencyStr = new String(doubleCurrencySign);
1613 
1614     /*Bug 4408066
1615       Add Field for the new method getIntegerInstance() [Richard/GCL]
1616     */
1617 
1618 
1619     /**
1620      * True if the the grouping (i.e. thousands) separator is used when
1621      * formatting and parsing numbers.
1622      *
1623      * @serial
1624      * @see #isGroupingUsed
1625      */
1626     private boolean groupingUsed = true;
1627 
1628     /**
1629      * The maximum number of digits allowed in the integer portion of a
1630      * number.  <code>maxIntegerDigits</code> must be greater than or equal to
1631      * <code>minIntegerDigits</code>.
1632      * <p>
1633      * <strong>Note:</strong> This field exists only for serialization
1634      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
1635      * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
1636      * When writing to a stream, <code>maxIntegerDigits</code> is set to
1637      * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
1638      * whichever is smaller.  When reading from a stream, this field is used
1639      * only if <code>serialVersionOnStream</code> is less than 1.
1640      *
1641      * @serial
1642      * @see #getMaximumIntegerDigits
1643      */
1644     private byte    maxIntegerDigits = 40;
1645 
1646     /**
1647      * The minimum number of digits allowed in the integer portion of a
1648      * number.  <code>minimumIntegerDigits</code> must be less than or equal to
1649      * <code>maximumIntegerDigits</code>.
1650      * <p>
1651      * <strong>Note:</strong> This field exists only for serialization
1652      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
1653      * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
1654      * When writing to a stream, <code>minIntegerDigits</code> is set to
1655      * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
1656      * whichever is smaller.  When reading from a stream, this field is used
1657      * only if <code>serialVersionOnStream</code> is less than 1.
1658      *
1659      * @serial
1660      * @see #getMinimumIntegerDigits
1661      */
1662     private byte    minIntegerDigits = 1;
1663 
1664     /**
1665      * The maximum number of digits allowed in the fractional portion of a
1666      * number.  <code>maximumFractionDigits</code> must be greater than or equal to
1667      * <code>minimumFractionDigits</code>.
1668      * <p>
1669      * <strong>Note:</strong> This field exists only for serialization
1670      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
1671      * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
1672      * When writing to a stream, <code>maxFractionDigits</code> is set to
1673      * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
1674      * whichever is smaller.  When reading from a stream, this field is used
1675      * only if <code>serialVersionOnStream</code> is less than 1.
1676      *
1677      * @serial
1678      * @see #getMaximumFractionDigits
1679      */
1680     private byte    maxFractionDigits = 3;    // invariant, >= minFractionDigits
1681 
1682     /**
1683      * The minimum number of digits allowed in the fractional portion of a
1684      * number.  <code>minimumFractionDigits</code> must be less than or equal to
1685      * <code>maximumFractionDigits</code>.
1686      * <p>
1687      * <strong>Note:</strong> This field exists only for serialization
1688      * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
1689      * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
1690      * When writing to a stream, <code>minFractionDigits</code> is set to
1691      * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
1692      * whichever is smaller.  When reading from a stream, this field is used
1693      * only if <code>serialVersionOnStream</code> is less than 1.
1694      *
1695      * @serial
1696      * @see #getMinimumFractionDigits
1697      */
1698     private byte    minFractionDigits = 0;
1699 
1700     /**
1701      * True if this format will parse numbers as integers only.
1702      *
1703      * @serial
1704      * @see #isParseIntegerOnly
1705      */
1706     private boolean parseIntegerOnly = false;
1707 
1708     // new fields for 1.2.  byte is too small for integer digits.
1709 
1710     /**
1711      * The maximum number of digits allowed in the integer portion of a
1712      * number.  <code>maximumIntegerDigits</code> must be greater than or equal to
1713      * <code>minimumIntegerDigits</code>.
1714      *
1715      * @serial
1716      * @see #getMaximumIntegerDigits
1717      */
1718     private int    maximumIntegerDigits = 40;
1719 
1720     /**
1721      * The minimum number of digits allowed in the integer portion of a
1722      * number.  <code>minimumIntegerDigits</code> must be less than or equal to
1723      * <code>maximumIntegerDigits</code>.
1724      *
1725      * @serial
1726      * @see #getMinimumIntegerDigits
1727      */
1728     private int    minimumIntegerDigits = 1;
1729 
1730     /**
1731      * The maximum number of digits allowed in the fractional portion of a
1732      * number.  <code>maximumFractionDigits</code> must be greater than or equal to
1733      * <code>minimumFractionDigits</code>.
1734      *
1735      * @serial
1736      * @see #getMaximumFractionDigits
1737      */
1738     private int    maximumFractionDigits = 3;    // invariant, >= minFractionDigits
1739 
1740     /**
1741      * The minimum number of digits allowed in the fractional portion of a
1742      * number.  <code>minimumFractionDigits</code> must be less than or equal to
1743      * <code>maximumFractionDigits</code>.
1744      *
1745      * @serial
1746      * @see #getMinimumFractionDigits
1747      */
1748     private int    minimumFractionDigits = 0;
1749 
1750     /**
1751      * Currency object used to format currencies.  Subclasses may
1752      * ignore this if they are not currency formats.  This will be
1753      * null unless a subclass sets it to a non-null value.
1754      */
1755     private Currency currency;
1756 
1757     static final int currentSerialVersion = 2;
1758 
1759     /**
1760      * Describes the version of <code>NumberFormat</code> present on the stream.
1761      * Possible values are:
1762      * <ul>
1763      * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
1764      *     In this version, the <code>int</code> fields such as
1765      *     <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
1766      *     fields such as <code>maxIntegerDigits</code> are used instead.
1767      *
1768      * <li><b>1</b>: the JDK 1.2 version of the stream format.  The values of the
1769      *     <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
1770      *     and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
1771      *     are used instead.
1772      *
1773      * <li><b>2</b>: adds capitalizationSetting.
1774      * </ul>
1775      * When streaming out a <code>NumberFormat</code>, the most recent format
1776      * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
1777      * is always written.
1778      *
1779      * @serial
1780      */
1781     private int serialVersionOnStream = currentSerialVersion;
1782 
1783     // Removed "implements Cloneable" clause.  Needs to update serialization
1784     // ID for backward compatibility.
1785     private static final long serialVersionUID = -2308460125733713944L;
1786 
1787     /**
1788      * Empty constructor.  Public for API compatibility with historic versions of
1789      * {@link java.text.NumberFormat} which had public constructor even though this is
1790      * an abstract class.
1791      */
NumberFormat()1792     public NumberFormat() {
1793     }
1794 
1795     // new in ICU4J 3.6
1796     private boolean parseStrict;
1797 
1798     /*
1799      * Capitalization context setting, new in ICU 53
1800      * @serial
1801      */
1802     private DisplayContext capitalizationSetting = DisplayContext.CAPITALIZATION_NONE;
1803 
1804     /**
1805      * The instances of this inner class are used as attribute keys and values
1806      * in AttributedCharacterIterator that
1807      * NumberFormat.formatToCharacterIterator() method returns.
1808      * <p>
1809      * There is no public constructor to this class, the only instances are the
1810      * constants defined here.
1811      * <p>
1812      */
1813     public static class Field extends Format.Field {
1814         // generated by serialver from JDK 1.4.1_01
1815         static final long serialVersionUID = -4516273749929385842L;
1816 
1817         /**
1818          */
1819         public static final Field SIGN = new Field("sign");
1820 
1821         /**
1822          */
1823         public static final Field INTEGER = new Field("integer");
1824 
1825         /**
1826          */
1827         public static final Field FRACTION = new Field("fraction");
1828 
1829         /**
1830          */
1831         public static final Field EXPONENT = new Field("exponent");
1832 
1833         /**
1834          */
1835         public static final Field EXPONENT_SIGN = new Field("exponent sign");
1836 
1837         /**
1838          */
1839         public static final Field EXPONENT_SYMBOL = new Field("exponent symbol");
1840 
1841         /**
1842          */
1843         public static final Field DECIMAL_SEPARATOR = new Field("decimal separator");
1844         /**
1845          */
1846         public static final Field GROUPING_SEPARATOR = new Field("grouping separator");
1847 
1848         /**
1849          */
1850         public static final Field PERCENT = new Field("percent");
1851 
1852         /**
1853          */
1854         public static final Field PERMILLE = new Field("per mille");
1855 
1856         /**
1857          */
1858         public static final Field CURRENCY = new Field("currency");
1859 
1860         /**
1861          */
1862         public static final Field MEASURE_UNIT = new Field("measure unit");
1863 
1864         /**
1865          */
1866         public static final Field COMPACT = new Field("compact");
1867 
1868         /**
1869          * Constructs a new instance of NumberFormat.Field with the given field
1870          * name.
1871          */
Field(String fieldName)1872         protected Field(String fieldName) {
1873             super(fieldName);
1874         }
1875 
1876         /**
1877          * serizalization method resolve instances to the constant
1878          * NumberFormat.Field values
1879          */
1880         @Override
readResolve()1881         protected Object readResolve() throws InvalidObjectException {
1882             if (this.getName().equals(INTEGER.getName()))
1883                 return INTEGER;
1884             if (this.getName().equals(FRACTION.getName()))
1885                 return FRACTION;
1886             if (this.getName().equals(EXPONENT.getName()))
1887                 return EXPONENT;
1888             if (this.getName().equals(EXPONENT_SIGN.getName()))
1889                 return EXPONENT_SIGN;
1890             if (this.getName().equals(EXPONENT_SYMBOL.getName()))
1891                 return EXPONENT_SYMBOL;
1892             if (this.getName().equals(CURRENCY.getName()))
1893                 return CURRENCY;
1894             if (this.getName().equals(DECIMAL_SEPARATOR.getName()))
1895                 return DECIMAL_SEPARATOR;
1896             if (this.getName().equals(GROUPING_SEPARATOR.getName()))
1897                 return GROUPING_SEPARATOR;
1898             if (this.getName().equals(PERCENT.getName()))
1899                 return PERCENT;
1900             if (this.getName().equals(PERMILLE.getName()))
1901                 return PERMILLE;
1902             if (this.getName().equals(SIGN.getName()))
1903                 return SIGN;
1904             if (this.getName().equals(MEASURE_UNIT.getName()))
1905                 return MEASURE_UNIT;
1906             if (this.getName().equals(COMPACT.getName()))
1907                 return COMPACT;
1908 
1909             throw new InvalidObjectException("An invalid object.");
1910         }
1911     }
1912 }
1913