8329222: java.text.NumberFormat (and subclasses) spec updates

Reviewed-by: naoto
This commit is contained in:
Justin Lu 2024-04-23 21:10:46 +00:00
parent 2555166247
commit f60798a30e
3 changed files with 421 additions and 391 deletions

View File

@ -47,80 +47,113 @@ import java.util.stream.Collectors;
/** /**
* <p> * <p>
* {@code CompactNumberFormat} is a concrete subclass of {@code NumberFormat} * {@code CompactNumberFormat} is a concrete subclass of {@code NumberFormat}
* that formats a decimal number in its compact form. * that formats a decimal number in a localized compact form.
* * Compact number formatting is designed for an environment with limited space.
* The compact number formatting is designed for the environment where the space * For example, displaying the formatted number {@code 7M} instead of {@code
* is limited, and the formatted string can be displayed in that limited space. * 7,000,000.00} in the {@link java.util.Locale#US US locale}. The {@code
* It is defined by LDML's specification for * CompactNumberFormat} class is defined by LDML's specification for
* <a href = "http://unicode.org/reports/tr35/tr35-numbers.html#Compact_Number_Formats"> * <a href = "http://unicode.org/reports/tr35/tr35-numbers.html#Compact_Number_Formats">
* Compact Number Formats</a>. A compact number formatting refers * Compact Number Formats</a>.
* to the representation of a number in a shorter form, based on the patterns
* provided for a given locale.
* *
* <p> * <h2>Getting a CompactNumberFormat</h2>
* For example: * To get a compact number format, use one of the ways listed below.
* <br>In the {@link java.util.Locale#US US locale}, {@code 1000} can be formatted * <ul>
* as {@code "1K"}, and {@code 1000000} as {@code "1M"}, depending upon the * <li> Use the factory method {@link NumberFormat#getCompactNumberInstance()}
* {@linkplain ##compact_number_style style} used. * to obtain a format for the default locale with
* <br>In the {@code "hi_IN"} locale, {@code 1000} can be formatted as * {@link NumberFormat.Style#SHORT SHORT} style.
* "1 \u0939\u091C\u093C\u093E\u0930", and {@code 50000000} as "5 \u0915.", * <li> Use the factory methood {@link NumberFormat#getCompactNumberInstance(Locale, Style)}
* depending upon the {@linkplain ##compact_number_style style} used. * to obtain a format for a different locale
* * and to control the {@linkplain ##compact_number_style Style}.
* <p> * <li> Use one of the {@code CompactNumberFormat} constructors, for example, {@link
* To obtain a {@code CompactNumberFormat} for a locale, use one * CompactNumberFormat#CompactNumberFormat(String, DecimalFormatSymbols, String[])
* of the factory methods given by {@code NumberFormat} for compact number * CompactNumberFormat(decimalPattern, symbols, compactPatterns)}, to obtain a
* formatting. For example, * {@code CompactNumberFormat} with further customization.
* {@link NumberFormat#getCompactNumberInstance(Locale, Style)}. * </ul>
* * <p>If a standard compact format for a given locale and {@link
* <blockquote>{@snippet lang=java : * ##compact_number_style style} is desired, it is recommended to use one of the
* NumberFormat fmt = NumberFormat.getCompactNumberInstance( * NumberFormat factory methods listed above. To use an instance method
* Locale.forLanguageTag("hi-IN"), NumberFormat.Style.SHORT); * defined by {@code CompactNumberFormat}, the {@code NumberFormat} returned by
* String result = fmt.format(1000); * these factory methods should be type checked before converted to {@code CompactNumberFormat}.
* }</blockquote> * If the installed locale-sensitive service implementation does not support
* the given {@code Locale}, the parent locale chain will be looked up, and
* a {@code Locale} used that is supported.
* *
* <h2><a id="compact_number_style">Style</a></h2> * <h2><a id="compact_number_style">Style</a></h2>
* <p> * When using {@link NumberFormat#getCompactNumberInstance(Locale, Style)}, a
* A number can be formatted in the compact forms with two different * compact form can be retrieved with either a {@link NumberFormat.Style#SHORT
* styles, {@link NumberFormat.Style#SHORT SHORT} * SHORT} or {@link NumberFormat.Style#LONG LONG} style.
* and {@link NumberFormat.Style#LONG LONG}. Use * For example, a {@link NumberFormat.Style#SHORT SHORT} style compact number instance in
* {@link NumberFormat#getCompactNumberInstance(Locale, Style)} for formatting and * the {@link java.util.Locale#US US locale} formats {@code 10000} as {@code
* parsing a number in {@link NumberFormat.Style#SHORT SHORT} or * "10K"}. However, a {@link NumberFormat.Style#LONG LONG} style instance in
* {@link NumberFormat.Style#LONG LONG} compact form, * the same locale formats {@code 10000} as {@code "10 thousand"}.
* where the given {@code Style} parameter requests the desired *
* format. A {@link NumberFormat.Style#SHORT SHORT} style * <h2>Using CompactNumberFormat</h2>
* compact number instance in the {@link java.util.Locale#US US locale} formats * The following is an example of formatting and parsing in a localized manner,
* {@code 10000} as {@code "10K"}. However, a *
* {@link NumberFormat.Style#LONG LONG} style instance in same locale * {@snippet lang=java :
* formats {@code 10000} as {@code "10 thousand"}. * NumberFormat compactFormat = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
* compactFormat.format(1000); // returns "1K"
* compactFormat.parse("1K"); // returns 1000
* }
*
* <h2 id="formatting">Formatting</h2>
* The default formatting behavior returns a formatted string with no fractional
* digits, however users can use the {@link #setMinimumFractionDigits(int)}
* method to include the fractional part.
* The number {@code 1000.0} or {@code 1000} is formatted as {@code "1K"}
* not {@code "1.00K"} (in the {@link java.util.Locale#US US locale}). For this
* reason, the patterns provided for formatting contain only the minimum
* integer digits, prefix and/or suffix, but no fractional part.
* For example, patterns used are {@code {"", "", "", 0K, 00K, ...}}. If the pattern
* selected for formatting a number is {@code "0"} (special pattern),
* either explicit or defaulted, then the general number formatting provided by
* {@link java.text.DecimalFormat DecimalFormat}
* for the specified locale is used.
*
* <h3>Rounding</h3>
* {@code CompactNumberFormat} provides rounding modes defined in
* {@link java.math.RoundingMode} for formatting. By default, it uses
* {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
*
* <h2>Parsing</h2>
* The default parsing behavior does not allow a grouping separator until
* grouping used is set to {@code true} by using
* {@link #setGroupingUsed(boolean)}. The parsing of the fractional part
* depends on the {@link #isParseIntegerOnly()}. For example, if the
* parse integer only is set to true, then the fractional part is skipped.
* *
* <h2><a id="compact_number_patterns">Compact Number Patterns</a></h2> * <h2><a id="compact_number_patterns">Compact Number Patterns</a></h2>
* <p> * <p>
* The compact number patterns are represented in a series of patterns where each * The {@code compactPatterns} in {@link
* pattern is used to format a range of numbers. An example of * CompactNumberFormat#CompactNumberFormat(String, DecimalFormatSymbols, String[])
* {@link NumberFormat.Style#SHORT SHORT} styled compact number patterns * CompactNumberFormat(decimalPattern, symbols, compactPatterns)} are represented
* as a series of strings, where each string is a {@link ##compact_number_syntax
* pattern} that is used to format a range of numbers.
*
* <p> An example of the {@link NumberFormat.Style#SHORT SHORT} styled compact number patterns
* for the {@link java.util.Locale#US US locale} is {@code {"", "", "", "0K", * for the {@link java.util.Locale#US US locale} is {@code {"", "", "", "0K",
* "00K", "000K", "0M", "00M", "000M", "0B", "00B", "000B", "0T", "00T", "000T"}}, * "00K", "000K", "0M", "00M", "000M", "0B", "00B", "000B", "0T", "00T", "000T"}},
* ranging from {@code 10}<sup>{@code 0}</sup> to {@code 10}<sup>{@code 14}</sup>. * ranging from {@code 10}<sup>{@code 0}</sup> to {@code 10}<sup>{@code 14}</sup>.
* There can be any number of patterns and they are * There can be any number of patterns and they are
* strictly index based starting from the range {@code 10}<sup>{@code 0}</sup>. * strictly index based starting from the range {@code 10}<sup>{@code 0}</sup>.
* For example, in the above patterns, pattern at index 3 * For example, in the above patterns, the pattern at index 3
* ({@code "0K"}) is used for formatting {@code number >= 1000 and number < 10000}, * ({@code "0K"}) is used for formatting a number in the range: {@code 1000 <= number < 10000},
* pattern at index 4 ({@code "00K"}) is used for formatting * index 4 ({@code "00K"}) for formatting a number the range: {@code 10000 <=
* {@code number >= 10000 and number < 100000} and so on. In most of the locales, * number < 100000}, and so forth.
* patterns with the range * <p>In most locales, patterns with the range
* {@code 10}<sup>{@code 0}</sup>-{@code 10}<sup>{@code 2}</sup> are empty * {@code 10}<sup>{@code 0}</sup>-{@code 10}<sup>{@code 2}</sup> are empty
* strings, which implicitly means a special pattern {@code "0"}. * strings, which implicitly means a special pattern {@code "0"}.
* A special pattern {@code "0"} is used for any range which does not contain * A special pattern {@code "0"} is used for any range which does not contain
* a compact pattern. This special pattern can appear explicitly for any specific * a compact pattern. This special pattern can appear explicitly for any specific
* range, or considered as a default pattern for an empty string. * range, or considered as a default pattern for an empty string.
* *
* <p> * <h3>Negative Subpatterns</h3>
* A compact pattern contains a positive and negative subpattern * A compact pattern contains a positive and negative subpattern
* separated by a subpattern boundary character {@code ';' (U+003B)}, * separated by a subpattern boundary character {@code ';'},
* for example, {@code "0K;-0K"}. Each subpattern has a prefix, * for example, {@code "0K;-0K"}. Each subpattern has a prefix,
* minimum integer digits, and suffix. The negative subpattern * minimum integer digits, and suffix. The negative subpattern
* is optional, if absent, then the positive subpattern prefixed with the * is optional, if absent, then the positive subpattern prefixed with the
* minus sign ({@code '-' U+002D HYPHEN-MINUS}) is used as the negative * minus sign {@code '-' (U+002D HYPHEN-MINUS)} is used as the negative
* subpattern. That is, {@code "0K"} alone is equivalent to {@code "0K;-0K"}. * subpattern. That is, {@code "0K"} alone is equivalent to {@code "0K;-0K"}.
* If there is an explicit negative subpattern, it serves only to specify * If there is an explicit negative subpattern, it serves only to specify
* the negative prefix and suffix. The number of minimum integer digits, * the negative prefix and suffix. The number of minimum integer digits,
@ -128,31 +161,35 @@ import java.util.stream.Collectors;
* That means that {@code "0K;-00K"} produces precisely the same behavior * That means that {@code "0K;-00K"} produces precisely the same behavior
* as {@code "0K;-0K"}. * as {@code "0K;-0K"}.
* *
* <p> * <h4>Escaping Special Characters</h4>
* Many characters in a compact pattern are taken literally, they are matched * Many characters in a compact pattern are taken literally, they are matched
* during parsing and output unchanged during formatting. * during parsing and output unchanged during formatting.
* {@linkplain DecimalFormat##special_pattern_character Special characters}, * {@linkplain DecimalFormat##special_pattern_character Special characters},
* on the other hand, stand for other characters, strings, or classes of * on the other hand, stand for other characters, strings, or classes of
* characters. They must be quoted, using single quote {@code ' (U+0027)} * characters. These characters must be quoted using single quotes {@code ' (U+0027)}
* unless noted otherwise, if they are to appear in the prefix or suffix * unless noted otherwise, if they are to appear in the prefix or suffix
* as literals. For example, 0\u0915'.'. * as literals. For example, 0\u0915'.'.
* *
* <h3>Plurals</h3> * <h3>Plurals</h3>
* <p> {@code CompactNumberFormat} support patterns for both singular and plural
* compact forms. For the plural form, the {@code Pattern} should consist
* of {@code PluralPattern}(s) separated by a space ' ' (U+0020) that are enumerated
* within a pair of curly brackets '{' (U+007B) and '}' (U+007D).
* In this format, each {@code PluralPattern} consists of its {@code count},
* followed by a single colon {@code ':' (U+003A)} and a {@code SimplePattern}.
* As a space is reserved for separating subsequent {@code PluralPattern}s, it must
* be quoted to be used literally in either the {@code prefix} or {@code suffix}.
* <p> * <p>
* In case some localization requires compact number patterns to be different for * For example, while the pattern representing millions ({@code 10}<sup>{@code 6}
* plurals, each singular and plural pattern can be enumerated within a pair of * </sup>) in the US locale can be specified as the SimplePattern: {@code "0 Million"}, for the
* curly brackets <code>'{' (U+007B)</code> and <code>'}' (U+007D)</code>, separated * German locale it can be specified as the PluralPattern:
* by a space {@code ' ' (U+0020)}. If this format is used, each pattern needs to be * {@code "{one:0' 'Million other:0' 'Millionen}"}.
* prepended by its {@code count}, followed by a single colon {@code ':' (U+003A)}. *
* If the pattern includes spaces literally, they must be quoted.
* <p> * <p>
* For example, the compact number pattern representing millions in German locale can be * <a id="compact_number_syntax">A compact pattern has the following syntax, with {@code count}</a>
* specified as {@code "{one:0' 'Million other:0' 'Millionen}"}. The {@code count} * following LDML's
* follows LDML's
* <a href="https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules"> * <a href="https://unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules">
* Language Plural Rules</a>. * Language Plural Rules</a>:
* <p>
* A compact pattern has the following syntax:
* <blockquote><pre> * <blockquote><pre>
* <i>Pattern:</i> * <i>Pattern:</i>
* <i>SimplePattern</i> * <i>SimplePattern</i>
@ -179,37 +216,12 @@ import java.util.stream.Collectors;
* 0 <i>MinimumInteger</i> * 0 <i>MinimumInteger</i>
* </pre></blockquote> * </pre></blockquote>
* *
* <h2>Formatting</h2>
* The default formatting behavior returns a formatted string with no fractional
* digits, however users can use the {@link #setMinimumFractionDigits(int)}
* method to include the fractional part.
* The number {@code 1000.0} or {@code 1000} is formatted as {@code "1K"}
* not {@code "1.00K"} (in the {@link java.util.Locale#US US locale}). For this
* reason, the patterns provided for formatting contain only the minimum
* integer digits, prefix and/or suffix, but no fractional part.
* For example, patterns used are {@code {"", "", "", 0K, 00K, ...}}. If the pattern
* selected for formatting a number is {@code "0"} (special pattern),
* either explicit or defaulted, then the general number formatting provided by
* {@link java.text.DecimalFormat DecimalFormat}
* for the specified locale is used.
*
* <h2>Parsing</h2>
* The default parsing behavior does not allow a grouping separator until
* grouping used is set to {@code true} by using
* {@link #setGroupingUsed(boolean)}. The parsing of the fractional part
* depends on the {@link #isParseIntegerOnly()}. For example, if the
* parse integer only is set to true, then the fractional part is skipped.
*
* <h2>Rounding</h2>
* {@code CompactNumberFormat} provides rounding modes defined in
* {@link java.math.RoundingMode} for formatting. By default, it uses
* {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
*
* @spec https://www.unicode.org/reports/tr35 * @spec https://www.unicode.org/reports/tr35
* Unicode Locale Data Markup Language (LDML) * Unicode Locale Data Markup Language (LDML)
* @see NumberFormat.Style * @see NumberFormat.Style
* @see NumberFormat * @see NumberFormat
* @see DecimalFormat * @see DecimalFormat
* @see Locale
* @since 12 * @since 12
*/ */
public final class CompactNumberFormat extends NumberFormat { public final class CompactNumberFormat extends NumberFormat {
@ -389,10 +401,19 @@ public final class CompactNumberFormat extends NumberFormat {
* To obtain the instance of {@code CompactNumberFormat} with the standard * To obtain the instance of {@code CompactNumberFormat} with the standard
* compact patterns for a {@code Locale} and {@code Style}, * compact patterns for a {@code Locale} and {@code Style},
* it is recommended to use the factory methods given by * it is recommended to use the factory methods given by
* {@code NumberFormat} for compact number formatting. For example, * {@code NumberFormat} for compact number formatting.
* {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
* *
* @param decimalPattern a decimal pattern for general number formatting * <p>Below is an example of using the constructor,
*
* {@snippet lang=java :
* String[] compactPatterns = {"", "", "", "a lot"};
* NumberFormat fmt = new CompactNumberFormat("00", DecimalFormatSymbols.getInstance(Locale.US), compactPatterns);
* fmt.format(1); // returns "01"
* fmt.format(1000); // returns "a lot"
* }
*
* @param decimalPattern a {@linkplain DecimalFormat##patterns decimal pattern}
* for general number formatting
* @param symbols the set of symbols to be used * @param symbols the set of symbols to be used
* @param compactPatterns an array of * @param compactPatterns an array of
* {@linkplain ##compact_number_patterns compact number patterns} * {@linkplain ##compact_number_patterns compact number patterns}
@ -419,7 +440,8 @@ public final class CompactNumberFormat extends NumberFormat {
* {@code NumberFormat} for compact number formatting. For example, * {@code NumberFormat} for compact number formatting. For example,
* {@link NumberFormat#getCompactNumberInstance(Locale, Style)}. * {@link NumberFormat#getCompactNumberInstance(Locale, Style)}.
* *
* @param decimalPattern a decimal pattern for general number formatting * @param decimalPattern a {@linkplain DecimalFormat##patterns decimal pattern}
* for general number formatting
* @param symbols the set of symbols to be used * @param symbols the set of symbols to be used
* @param compactPatterns an array of * @param compactPatterns an array of
* {@linkplain ##compact_number_patterns compact number patterns} * {@linkplain ##compact_number_patterns compact number patterns}

View File

@ -56,45 +56,104 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
/** /**
* {@code DecimalFormat} is a concrete subclass of * {@code DecimalFormat} is a concrete subclass of
* {@code NumberFormat} that formats decimal numbers. It has a variety of * {@code NumberFormat} that formats decimal numbers in a localized manner.
* features designed to make it possible to parse and format numbers in any * It has a variety of features designed to make it possible to parse and format
* locale, including support for Western, Arabic, and Indic digits. It also * numbers in any locale, including support for Western, Arabic, and Indic digits.
* supports different kinds of numbers, including integers (123), fixed-point * It also supports different kinds of numbers, including integers (123), fixed-point
* numbers (123.4), scientific notation (1.23E4), percentages (12%), and * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
* currency amounts ($123). All of these can be localized. * currency amounts ($123).
* *
* <p>To obtain a {@code NumberFormat} for a specific locale, including the * <h2>Getting a DecimalFormat</h2>
* default locale, call one of {@code NumberFormat}'s factory methods, such
* as {@code getInstance()}. In general, do not call the
* {@code DecimalFormat} constructors directly, since the
* {@code NumberFormat} factory methods may return subclasses other than
* {@code DecimalFormat}. If you need to customize the format object, do
* something like this:
* *
* <blockquote>{@snippet lang=java : * To obtain a standard decimal format for a specific locale, including the default locale,
* NumberFormat numFormat = NumberFormat.getInstance(loc); * it is recommended to call one of the {@code NumberFormat}
* if (numFormat instanceof DecimalFormat decFormat) { * {@link NumberFormat##factory_methods factory methods}, such as {@link NumberFormat#getInstance()}.
* decFormat.setDecimalSeparatorAlwaysShown(true); * These factory methods may not always return a {@code DecimalFormat}
* depending on the locale-service provider implementation
* installed. Thus, to use an instance method defined by {@code DecimalFormat},
* the {@code NumberFormat} returned by the factory method should be
* type checked before converted to {@code DecimalFormat}. If the installed locale-sensitive
* service implementation does not support the given {@code Locale}, the parent
* locale chain will be looked up, and a {@code Locale} used that is supported.
*
* <p>If the factory methods are not desired, use one of the constructors such
* as {@link #DecimalFormat(String) DecimalFormat(String pattern)}. See the {@link
* ##patterns Pattern} section for more information on the {@code pattern} parameter.
*
* <h2>Using DecimalFormat</h2>
* The following is an example of formatting and parsing,
* {@snippet lang=java :
* NumberFormat nFmt = NumberFormat.getCurrencyInstance(Locale.US);
* if (nFmt instanceof DecimalFormat dFmt) {
* // pattern match to DecimalFormat to use setPositiveSuffix(String)
* dFmt.setPositiveSuffix(" dollars");
* dFmt.format(100000); // returns "$100,000.00 dollars"
* dFmt.parse("$100,000.00 dollars"); // returns 100000
* }
* } * }
* }</blockquote>
* *
* <p>A {@code DecimalFormat} comprises a <em>pattern</em> and a set of
* <em>symbols</em>. The pattern may be set directly using
* {@code applyPattern()}, or indirectly using the API methods. The
* symbols are stored in a {@code DecimalFormatSymbols} object. When using
* the {@code NumberFormat} factory methods, the pattern and symbols are
* read from localized {@code ResourceBundle}s.
* *
* <h2 id="patterns">Patterns</h2> * <h2 id="formatting">Formatting and Parsing</h2>
* <h3 id="rounding">Rounding</h3>
* *
* Note: For any given {@code DecimalFormat} pattern, if the pattern is not * When formatting, {@code DecimalFormat} can adjust its rounding using {@link
* in scientific notation, the maximum number of integer digits will not be * #setRoundingMode(RoundingMode)}. By default, it uses
* derived from the pattern, and instead set to {@link Integer#MAX_VALUE}. * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
* Otherwise, if the pattern is in scientific notation, the maximum number of *
* integer digits will be derived from the pattern. This derivation is detailed * <h3>Digits</h3>
* in the {@link ##scientific_notation Scientific Notation} section. This behavior *
* is the typical end-user desire; {@link #setMaximumIntegerDigits(int)} can be * When formatting, {@code DecimalFormat} uses the ten consecutive
* used to manually adjust the maximum integer digits. * characters starting with the localized zero digit defined in the
* {@code DecimalFormatSymbols} object as digits.
* <p>When parsing, these digits as well as all Unicode decimal digits, as
* defined by {@link Character#digit Character.digit}, are recognized.
*
* <h3 id="digit_limits"> Integer and Fraction Digit Limits </h3>
* @implSpec
* When formatting a {@code Number} other than {@code BigInteger} and
* {@code BigDecimal}, {@code 309} is used as the upper limit for integer digits,
* and {@code 340} as the upper limit for fraction digits. This occurs, even if
* one of the {@code DecimalFormat} getter methods, for example, {@link #getMinimumFractionDigits()}
* returns a numerically greater value.
*
* <h3>Special Values</h3>
* <ul>
* <li><p><b>Not a Number</b> ({@code NaN}) is formatted as a string,
* which is typically given as "NaN". This string is determined by {@link
* DecimalFormatSymbols#getNaN()}. This is the only value for which the prefixes
* and suffixes are not attached.
*
* <li><p><b>Infinity</b> is formatted as a string, which is typically given as
* "&#8734;" ({@code U+221E}), with the positive or negative prefixes and suffixes
* attached. This string is determined by {@link DecimalFormatSymbols#getInfinity()}.
*
* <li><p><b>Negative zero</b> ({@code "-0"}) parses to
* <ul>
* <li>{@code BigDecimal(0)} if {@code isParseBigDecimal()} is
* true
* <li>{@code Long(0)} if {@code isParseBigDecimal()} is false
* and {@code isParseIntegerOnly()} is true
* <li>{@code Double(-0.0)} if both {@code isParseBigDecimal()}
* and {@code isParseIntegerOnly()} are false
* </ul>
* </ul>
*
* <h2><a id="synchronization">Synchronization</a></h2>
*
* <p>
* Decimal formats are generally not synchronized.
* It is recommended to create separate format instances for each thread.
* If multiple threads access a format concurrently, it must be synchronized
* externally.
*
* <h2 id="patterns">DecimalFormat Pattern</h2>
*
* A {@code DecimalFormat} comprises a <em>pattern</em> and a set of
* <em>symbols</em>. The pattern may be set directly using {@code applyPattern()},
* or indirectly using the various API methods. The symbols are stored in a {@code
* DecimalFormatSymbols} object. When using the {@code NumberFormat} factory
* methods, the pattern and symbols are created from the locale-sensitive service
* implementation installed.
* *
* <p> {@code DecimalFormat} patterns have the following syntax: * <p> {@code DecimalFormat} patterns have the following syntax:
* <blockquote><pre> * <blockquote><pre>
@ -135,11 +194,115 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
* 0 <i>MinimumExponent<sub>opt</sub></i> * 0 <i>MinimumExponent<sub>opt</sub></i>
* </pre></blockquote> * </pre></blockquote>
* *
* <p>A {@code DecimalFormat} pattern contains a positive and negative * <h3><a id="special_pattern_character">Special Pattern Characters</a></h3>
*
* <p>The special characters in the table below are interpreted syntactically when
* used in the DecimalFormat pattern.
* They must be quoted, unless noted otherwise, if they are to appear in the
* prefix or suffix as literals.
*
* <p> The characters in the {@code Symbol} column are used in non-localized
* patterns. The corresponding characters in the {@code Localized Symbol} column are used
* in localized patterns, with the characters in {@code Symbol} losing their
* syntactical meaning. Two exceptions are the currency sign ({@code U+00A4}) and
* quote ({@code U+0027}), which are not localized.
* <p>
* Non-localized patterns should be used when calling {@link #applyPattern(String)}.
* Localized patterns should be used when calling {@link #applyLocalizedPattern(String)}.
*
* <blockquote>
* <table class="striped">
* <caption style="display:none">Chart showing symbol, location, localized, and meaning.</caption>
* <thead>
* <tr>
* <th scope="col" style="text-align:left">Symbol
* <th scope="col" style="text-align:left">Localized Symbol
* <th scope="col" style="text-align:left">Location
* <th scope="col" style="text-align:left;width:50%">Meaning
* </thead>
* <tbody>
* <tr>
* <th scope="row">{@code 0}
* <td>{@link DecimalFormatSymbols#getZeroDigit()}
* <td>Number
* <td>Digit
* <tr>
* <th scope="row">{@code #}
* <td>{@link DecimalFormatSymbols#getDigit()}
* <td>Number
* <td>Digit, zero shows as absent
* <tr>
* <th scope="row">{@code .}
* <td>{@link DecimalFormatSymbols#getDecimalSeparator()}
* <td>Number
* <td>Decimal separator or monetary decimal separator
* <tr>
* <th scope="row">{@code - (U+002D)}
* <td>{@link DecimalFormatSymbols#getMinusSign()}
* <td>Number
* <td>Minus sign
* <tr>
* <th scope="row">{@code ,}
* <td>{@link DecimalFormatSymbols#getGroupingSeparator()}
* <td>Number
* <td>Grouping separator or monetary grouping separator
* <tr>
* <th scope="row">{@code E}
* <td>{@link DecimalFormatSymbols#getExponentSeparator()}
* <td>Number
* <td>Separates mantissa and exponent in scientific notation. This value
* is case sensistive. <em>Need not be quoted in prefix or suffix.</em>
* <tr>
* <th scope="row">{@code ;}
* <td>{@link DecimalFormatSymbols#getPatternSeparator()}
* <td>Subpattern boundary
* <td>Separates positive and negative subpatterns
* <tr>
* <th scope="row">{@code %}
* <td>{@link DecimalFormatSymbols#getPercent()}
* <td>Prefix or suffix
* <td>Multiply by 100 and show as percentage
* <tr>
* <th scope="row">&permil; ({@code U+2030})
* <td>{@link DecimalFormatSymbols#getPerMill()}
* <td>Prefix or suffix
* <td>Multiply by 1000 and show as per mille value
* <tr>
* <th scope="row">&#164; ({@code U+00A4})
* <td> n/a (not localized)
* <td>Prefix or suffix
* <td>Currency sign, replaced by currency symbol. If
* doubled, replaced by international currency symbol.
* If present in a pattern, the monetary decimal/grouping separators
* are used instead of the decimal/grouping separators.
* <tr>
* <th scope="row">{@code ' (U+0027)}
* <td> n/a (not localized)
* <td>Prefix or suffix
* <td>Used to quote special characters in a prefix or suffix,
* for example, {@code "'#'#"} formats 123 to
* {@code "#123"}. To create a single quote
* itself, use two in a row: {@code "# o''clock"}.
* </tbody>
* </table>
* </blockquote>
*
* <h3>Maximum Digits Derivation</h3>
* For any given {@code DecimalFormat} pattern, if the pattern is not
* in scientific notation, the maximum number of integer digits will not be
* derived from the pattern, and instead set to {@link Integer#MAX_VALUE}.
* Otherwise, if the pattern is in scientific notation, the maximum number of
* integer digits will be derived from the pattern. This derivation is detailed
* in the {@link ##scientific_notation Scientific Notation} section. {@link
* #setMaximumIntegerDigits(int)} can be used to manually adjust the maximum
* integer digits.
*
* <h3>Negative Subpatterns</h3>
* A {@code DecimalFormat} pattern contains a positive and negative
* subpattern, for example, {@code "#,##0.00;(#,##0.00)"}. Each * subpattern, for example, {@code "#,##0.00;(#,##0.00)"}. Each
* subpattern has a prefix, numeric part, and suffix. The negative subpattern * subpattern has a prefix, numeric part, and suffix. The negative subpattern
* is optional; if absent, then the positive subpattern prefixed with the * is optional; if absent, then the positive subpattern prefixed with the
* minus sign ({@code '-' U+002D HYPHEN-MINUS}) is used as the * minus sign {@code '-' (U+002D HYPHEN-MINUS)} is used as the
* negative subpattern. That is, {@code "0.00"} alone is equivalent to * negative subpattern. That is, {@code "0.00"} alone is equivalent to
* {@code "0.00;-0.00"}. If there is an explicit negative subpattern, it * {@code "0.00;-0.00"}. If there is an explicit negative subpattern, it
* serves only to specify the negative prefix and suffix; the number of digits, * serves only to specify the negative prefix and suffix; the number of digits,
@ -158,105 +321,15 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
* specified.) Another example is that the decimal separator and grouping * specified.) Another example is that the decimal separator and grouping
* separator should be distinct characters, or parsing will be impossible. * separator should be distinct characters, or parsing will be impossible.
* *
* <h3>Grouping Separator</h3>
* <p>The grouping separator is commonly used for thousands, but in some * <p>The grouping separator is commonly used for thousands, but in some
* countries it separates ten-thousands. The grouping size is a constant number * locales it separates ten-thousands. The grouping size is a constant number
* of digits between the grouping characters, such as 3 for 100,000,000 or 4 for * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
* 1,0000,0000. If you supply a pattern with multiple grouping characters, the * 1,0000,0000. If you supply a pattern with multiple grouping characters, the
* interval between the last one and the end of the integer is the one that is * interval between the last one and the end of the integer is the one that is
* used. So {@code "#,##,###,####"} == {@code "######,####"} == * used. For example, {@code "#,##,###,####"} == {@code "######,####"} ==
* {@code "##,####,####"}. * {@code "##,####,####"}.
* *
* <h3><a id="special_pattern_character">Special Pattern Characters</a></h3>
*
* <p>Many characters in a pattern are taken literally; they are matched during
* parsing and output unchanged during formatting. Special characters, on the
* other hand, stand for other characters, strings, or classes of characters.
* They must be quoted, unless noted otherwise, if they are to appear in the
* prefix or suffix as literals.
*
* <p>The characters listed here are used in non-localized patterns. Localized
* patterns use the corresponding characters taken from this formatter's
* {@code DecimalFormatSymbols} object instead, and these characters lose
* their special status. Two exceptions are the currency sign and quote, which
* are not localized.
*
* <blockquote>
* <table class="striped">
* <caption style="display:none">Chart showing symbol, location, localized, and meaning.</caption>
* <thead>
* <tr>
* <th scope="col" style="text-align:left">Symbol
* <th scope="col" style="text-align:left">Location
* <th scope="col" style="text-align:left">Localized?
* <th scope="col" style="text-align:left">Meaning
* </thead>
* <tbody>
* <tr style="vertical-align:top">
* <th scope="row">{@code 0}
* <td>Number
* <td>Yes
* <td>Digit
* <tr style="vertical-align: top">
* <th scope="row">{@code #}
* <td>Number
* <td>Yes
* <td>Digit, zero shows as absent
* <tr style="vertical-align:top">
* <th scope="row">{@code .}
* <td>Number
* <td>Yes
* <td>Decimal separator or monetary decimal separator
* <tr style="vertical-align: top">
* <th scope="row">{@code -}
* <td>Number
* <td>Yes
* <td>Minus sign
* <tr style="vertical-align:top">
* <th scope="row">{@code ,}
* <td>Number
* <td>Yes
* <td>Grouping separator or monetary grouping separator
* <tr style="vertical-align: top">
* <th scope="row">{@code E}
* <td>Number
* <td>Yes
* <td>Separates mantissa and exponent in scientific notation.
* <em>Need not be quoted in prefix or suffix.</em>
* <tr style="vertical-align:top">
* <th scope="row">{@code ;}
* <td>Subpattern boundary
* <td>Yes
* <td>Separates positive and negative subpatterns
* <tr style="vertical-align: top">
* <th scope="row">{@code %}
* <td>Prefix or suffix
* <td>Yes
* <td>Multiply by 100 and show as percentage
* <tr style="vertical-align:top">
* <th scope="row">{@code U+2030}
* <td>Prefix or suffix
* <td>Yes
* <td>Multiply by 1000 and show as per mille value
* <tr style="vertical-align: top">
* <th scope="row">&#164; ({@code U+00A4})
* <td>Prefix or suffix
* <td>No
* <td>Currency sign, replaced by currency symbol. If
* doubled, replaced by international currency symbol.
* If present in a pattern, the monetary decimal/grouping separators
* are used instead of the decimal/grouping separators.
* <tr style="vertical-align:top">
* <th scope="row">{@code '}
* <td>Prefix or suffix
* <td>No
* <td>Used to quote special characters in a prefix or suffix,
* for example, {@code "'#'#"} formats 123 to
* {@code "#123"}. To create a single quote
* itself, use two in a row: {@code "# o''clock"}.
* </tbody>
* </table>
* </blockquote>
*
* <h3 id="scientific_notation">Scientific Notation</h3> * <h3 id="scientific_notation">Scientific Notation</h3>
* *
* <p>Numbers in scientific notation are expressed as the product of a mantissa * <p>Numbers in scientific notation are expressed as the product of a mantissa
@ -339,95 +412,13 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
* <li>Exponential patterns may not contain grouping separators. * <li>Exponential patterns may not contain grouping separators.
* </ul> * </ul>
* *
* <h3>Rounding</h3> * @spec https://www.unicode.org/reports/tr35
* * Unicode Locale Data Markup Language (LDML)
* {@code DecimalFormat} provides rounding modes defined in
* {@link java.math.RoundingMode} for formatting. By default, it uses
* {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
*
* <h3>Digits</h3>
*
* For formatting, {@code DecimalFormat} uses the ten consecutive
* characters starting with the localized zero digit defined in the
* {@code DecimalFormatSymbols} object as digits. For parsing, these
* digits as well as all Unicode decimal digits, as defined by
* {@link Character#digit Character.digit}, are recognized.
*
* <h3 id="digit_limits"> Integer and Fraction Digit Limits </h3>
*
* @implSpec
* When formatting a {@code Number} other than {@code BigInteger} and
* {@code BigDecimal}, {@code 309} is used as the upper limit for integer digits,
* and {@code 340} as the upper limit for fraction digits. This occurs, even if
* one of the {@code DecimalFormat} getter methods, for example, {@link #getMinimumFractionDigits()}
* returns a numerically greater value.
*
* <h4>Special Values</h4>
*
* <p>Not a Number({@code NaN}) is formatted as a string, which typically has a
* single character {@code U+FFFD}. This string is determined by the
* {@code DecimalFormatSymbols} object. This is the only value for which
* the prefixes and suffixes are not used.
*
* <p>Infinity is formatted as a string, which typically has a single character
* {@code U+221E}, with the positive or negative prefixes and suffixes
* applied. The infinity string is determined by the
* {@code DecimalFormatSymbols} object.
*
* <p>Negative zero ({@code "-0"}) parses to
* <ul>
* <li>{@code BigDecimal(0)} if {@code isParseBigDecimal()} is
* true,
* <li>{@code Long(0)} if {@code isParseBigDecimal()} is false
* and {@code isParseIntegerOnly()} is true,
* <li>{@code Double(-0.0)} if both {@code isParseBigDecimal()}
* and {@code isParseIntegerOnly()} are false.
* </ul>
*
* <h3><a id="synchronization">Synchronization</a></h3>
*
* <p>
* Decimal formats are generally not synchronized.
* It is recommended to create separate format instances for each thread.
* If multiple threads access a format concurrently, it must be synchronized
* externally.
*
* <h3>Example</h3>
*
* <blockquote>{@snippet lang=java :
* // Print out a number using the localized number, integer, currency,
* // and percent format for each locale
* Locale[] locales = NumberFormat.getAvailableLocales();
* double myNumber = -1234.56;
* NumberFormat form;
* for (int j = 0; j < 4; ++j) {
* System.out.println("FORMAT");
* for (Locale locale : locales) {
* if (locale.getCountry().length() == 0) {
* continue; // Skip language-only locales
* }
* System.out.print(locale.getDisplayName());
* form = switch (j) {
* case 0 -> NumberFormat.getInstance(locale);
* case 1 -> NumberFormat.getIntegerInstance(locale);
* case 2 -> NumberFormat.getCurrencyInstance(locale);
* default -> NumberFormat.getPercentInstance(locale);
* };
* if (form instanceof DecimalFormat decForm) {
* System.out.print(": " + decForm.toPattern());
* }
* System.out.print(" -> " + form.format(myNumber));
* try {
* System.out.println(" -> " + form.parse(form.format(myNumber)));
* } catch (ParseException e) {}
* }
* }
* }</blockquote>
*
* @see <a href="http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a> * @see <a href="http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
* @see NumberFormat * @see NumberFormat
* @see DecimalFormatSymbols * @see DecimalFormatSymbols
* @see ParsePosition * @see ParsePosition
* @see Locale
* @author Mark Davis * @author Mark Davis
* @author Alan Liu * @author Alan Liu
* @since 1.1 * @since 1.1

View File

@ -59,102 +59,110 @@ import sun.util.locale.provider.LocaleServiceProviderPool;
/** /**
* {@code NumberFormat} is the abstract base class for all number * {@code NumberFormat} is the abstract base class for all number
* formats. This class provides the interface for formatting and parsing * formats. This class provides the interface for formatting and parsing
* numbers. {@code NumberFormat} also provides methods for determining * numbers in a localized manner. This enables code that can be completely
* which locales have number formats, and what their names are. * independent of the locale conventions for decimal points, thousands-separators,
* the particular decimal digits used, or whether the number format is even
* decimal. For example, this class could be used within an application to
* produce a number in a currency format according to the conventions of the desired
* locale.
* *
* <p> * <h2 id="factory_methods">Getting a NumberFormat</h2>
* {@code NumberFormat} helps you to format and parse numbers for any locale. * To get a {@code NumberFormat} for the default Locale, use one of the static
* Your code can be completely independent of the locale conventions for * factory methods that return a concrete subclass of {@code NumberFormat}.
* decimal points, thousands-separators, or even the particular decimal * The following formats all provide an example of formatting the {@code Number}
* digits used, or whether the number format is even decimal. * "2000.50" with the {@link java.util.Locale#US US} locale as the default locale.
* <ul>
* <li> Use {@link #getInstance()} or {@link #getNumberInstance()} to get
* a decimal format. For example, {@code "2,000.5"}.
* <li> Use {@link #getIntegerInstance()} to get an integer number format.
* For example, {@code "2,000"}.
* <li> Use {@link #getCurrencyInstance} to get a currency number format.
* For example, {@code "$2,000.50"}.
* <li> Use {@link #getCompactNumberInstance} to get a compact number format.
* For example, {@code "2K"}.
* <li> Use {@link #getPercentInstance} to get a format for displaying percentages.
* For example, {@code "200,050%"}.
* </ul>
* *
* <p> * Alternatively, if a {@code NumberFormat} for a different locale is required, use
* To format a number for the current Locale, use one of the factory * one of the overloaded factory methods that take {@code Locale} as a parameter,
* class methods: * for example, {@link #getIntegerInstance(Locale)}. If the installed locale-sensitive
* <blockquote> * service implementation does not support the given {@code Locale}, the parent
* {@snippet lang=java : * locale chain will be looked up, and a {@code Locale} used that is supported.
* myString = NumberFormat.getInstance().format(myNumber);
* }
* </blockquote>
* If you are formatting multiple numbers, it is
* more efficient to get the format and use it multiple times so that
* the system doesn't have to fetch the information about the local
* language and country conventions multiple times.
* <blockquote>
* {@snippet lang=java :
* NumberFormat nf = NumberFormat.getInstance();
* for (var myNumber : numbers) {
* output.println(nf.format(myNumber) + "; ");
* }
* }
* </blockquote>
* To format a number for a different Locale, specify it in the
* call to {@code getInstance}.
* <blockquote>
* {@snippet lang=java :
* NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
* }
* </blockquote>
* *
* <p>If the locale contains "nu" (numbers) and/or "rg" (region override) * <h3>Locale Extensions</h3>
* Formatting behavior can be changed when using a locale that contains any of the following
* <a href="../util/Locale.html#def_locale_extension">Unicode extensions</a>, * <a href="../util/Locale.html#def_locale_extension">Unicode extensions</a>,
* the decimal digits, and/or the country used for formatting are overridden. * <ul>
* <li> "nu"
* (<a href="https://unicode.org/reports/tr35/#UnicodeNumberSystemIdentifier">
* Numbering System</a>) - Overrides the decimal digits used
* <li> "rg"
* (<a href="https://unicode.org/reports/tr35/#RegionOverride">
* Region Override</a>) - Overrides the country used
* <li> "cf"
* (<a href="https://www.unicode.org/reports/tr35/tr35.html#UnicodeCurrencyFormatIdentifier">
* Currency Format style</a>) - Overrides the Currency Format style used
* </ul>
* <p>
* If both "nu" and "rg" are specified, the decimal digits from the "nu" * If both "nu" and "rg" are specified, the decimal digits from the "nu"
* extension supersedes the implicit one from the "rg" extension. * extension supersedes the implicit one from the "rg" extension.
* Although <a href="../util/Locale.html#def_locale_extension">Unicode extensions</a>
* defines various keys and values, actual locale-sensitive service implementations
* in a Java Runtime Environment might not support any particular Unicode locale
* attributes or key/type pairs.
* <p>Below is an example of a "US" locale currency format with accounting style,
* <blockquote>{@code NumberFormat.getCurrencyInstance(Locale.forLanguageTag("en-US-u-cf-account"));}</blockquote>
* With this style, a negative value is formatted enclosed in parentheses, instead
* of being prepended with a minus sign.
* *
* <p>You can also use a {@code NumberFormat} to parse numbers: * <h2>Using NumberFormat</h2>
* <blockquote> * The following is an example of formatting and parsing in a localized fashion,
* {@snippet lang=java : * {@snippet lang=java :
* myNumber = nf.parse(myString); * NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);
* currencyFormat.format(100000); // returns "$100,000.00"
* currencyFormat.parse("$100,000.00"); // returns 100000
* } * }
* </blockquote> *
* Use {@code getInstance} or {@code getNumberInstance} to get the * <h2>Customizing NumberFormat</h2>
* normal number format. Use {@code getIntegerInstance} to get an * {@code NumberFormat} provides API to customize formatting and parsing behavior,
* integer number format. Use {@code getCurrencyInstance} to get the * <ul>
* currency number format. Use {@code getCompactNumberInstance} to get the * <li> {@link #setParseIntegerOnly(boolean)}; when {@code true}, will only return the
* compact number format to format a number in shorter form. For example, * integer portion of the number parsed from the String.
* {@code 2000} can be formatted as {@code "2K"} in * <li> {@link #setMinimumFractionDigits(int)}; Use to adjust the expected digits when
* {@link java.util.Locale#US US locale}. Use {@code getPercentInstance} * formatting. Use any of the other minimum/maximum or fraction/integer setter methods
* to get a format for displaying percentages. With this format, a fraction * in the same manner.
* like 0.53 is displayed as 53%. * <li> {@link #setGroupingUsed(boolean)}; when {@code true}, formatted numbers will be displayed
* with grouping separators. Additionally, when {@code false}, parsing will not expect
* grouping separators in the parsed String.
* <li> {@link #setStrict(boolean)}; when {@code true}, parsing will be done strictly.
* The behavior of strict parsing should be referred to in the implementing
* {@code NumberFormat} subclass.
* </ul>
* *
* <p> * <p>
* You can also control the display of numbers with such methods as * To provide more control over formatting or parsing behavior, type checking can
* {@code setMinimumFractionDigits}. * be done to safely convert to an implementing subclass of {@code NumberFormat}; this
* If you want even more control over the format or parsing, * provides additional methods defined by the subclass.
* or want to give your users more control, * For example,
* you can try casting the {@code NumberFormat} you get from the factory methods * {@snippet lang=java :
* to a {@code DecimalFormat} or {@code CompactNumberFormat} depending on * NumberFormat nFmt = NumberFormat.getInstance(Locale.US);
* the factory method used. This will work for the vast majority of locales; * if (nFmt instanceof DecimalFormat dFmt) {
* just remember to put it in a {@code try} block in case you encounter * dFmt.setDecimalSeparatorAlwaysShown(true);
* an unusual one. * dFmt.format(100); // returns "100."
* }
* }
* The {@code NumberFormat} subclass returned by the factory methods is dependent
* on the locale-service provider implementation installed, and may not always
* be {@link DecimalFormat} or {@link CompactNumberFormat}.
* *
* <p> * <p>
* NumberFormat and DecimalFormat are designed such that some controls
* work for formatting and others work for parsing. The following is
* the detailed description for each these control methods,
* <p>
* setParseIntegerOnly : only affects parsing, e.g.
* if true, "3456.78" &rarr; 3456 (and leaves the parse position just after index 6)
* if false, "3456.78" &rarr; 3456.78 (and leaves the parse position just after index 8)
* This is independent of formatting. If you want to not show a decimal point
* where there might be no digits after the decimal point, use
* setDecimalSeparatorAlwaysShown.
* <p>
* setDecimalSeparatorAlwaysShown : only affects formatting, and only where
* there might be no digits after the decimal point, such as with a pattern
* like "#,##0.##", e.g.,
* if true, 3456.00 &rarr; "3,456."
* if false, 3456.00 &rarr; "3456"
* This is independent of parsing. If you want parsing to stop at the decimal
* point, use setParseIntegerOnly.
* <p>
* You can also use forms of the {@code parse} and {@code format} * You can also use forms of the {@code parse} and {@code format}
* methods with {@code ParsePosition} and {@code FieldPosition} to * methods with {@code ParsePosition} and {@code FieldPosition} to
* allow you to: * allow you to:
* <ul> * <ul>
* <li> progressively parse through pieces of a string * <li> Progressively parse through pieces of a string
* <li> align the decimal point and other areas * <li> Align the decimal point and other areas
* </ul> * </ul>
* For example, you can align numbers in two ways: * For example, you can align numbers in two ways:
* <ol> * <ol>
@ -197,15 +205,20 @@ import sun.util.locale.provider.LocaleServiceProviderPool;
* If multiple threads access a format concurrently, it must be synchronized * If multiple threads access a format concurrently, it must be synchronized
* externally. * externally.
* *
* @implSpec The {@link #format(double, StringBuffer, FieldPosition)}, * @implSpec
* Null Parameter Handling
* <ul>
* <li> The {@link #format(double, StringBuffer, FieldPosition)},
* {@link #format(long, StringBuffer, FieldPosition)} and * {@link #format(long, StringBuffer, FieldPosition)} and
* {@link #parse(String, ParsePosition)} methods may throw * {@link #parse(String, ParsePosition)} methods may throw
* {@code NullPointerException}, if any of their parameter is {@code null}. * {@code NullPointerException}, if any of their parameter is {@code null}.
* The subclass may provide its own implementation and specification about * The subclass may provide its own implementation and specification about
* {@code NullPointerException}. * {@code NullPointerException}.
* </ul>
* *
* <p> * Default RoundingMode
* The default implementation provides rounding modes defined * <ul>
* <li> The default implementation provides rounding modes defined
* in {@link java.math.RoundingMode} for formatting numbers. It * in {@link java.math.RoundingMode} for formatting numbers. It
* uses the {@linkplain java.math.RoundingMode#HALF_EVEN * uses the {@linkplain java.math.RoundingMode#HALF_EVEN
* round half-even algorithm}. To change the rounding mode use * round half-even algorithm}. To change the rounding mode use
@ -214,10 +227,14 @@ import sun.util.locale.provider.LocaleServiceProviderPool;
* configured to round floating point numbers using half-even * configured to round floating point numbers using half-even
* rounding (see {@link java.math.RoundingMode#HALF_EVEN * rounding (see {@link java.math.RoundingMode#HALF_EVEN
* RoundingMode.HALF_EVEN}) for formatting. * RoundingMode.HALF_EVEN}) for formatting.
* </ul>
* *
* @spec https://www.unicode.org/reports/tr35
* Unicode Locale Data Markup Language (LDML)
* @see DecimalFormat * @see DecimalFormat
* @see ChoiceFormat * @see ChoiceFormat
* @see CompactNumberFormat * @see CompactNumberFormat
* @see Locale
* @author Mark Davis * @author Mark Davis
* @author Helena Shih * @author Helena Shih
* @since 1.1 * @since 1.1