Path: blob/master/src/java.base/share/classes/java/text/NumberFormat.java
41152 views
/*1* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved27* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved28*29* The original version of this source code and documentation is copyrighted30* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These31* materials are provided under terms of a License Agreement between Taligent32* and Sun. This technology is protected by multiple US and International33* patents. This notice and attribution to Taligent may not be removed.34* Taligent is a registered trademark of Taligent, Inc.35*36*/3738package java.text;3940import java.io.InvalidObjectException;41import java.io.IOException;42import java.io.ObjectInputStream;43import java.io.ObjectOutputStream;44import java.math.BigInteger;45import java.math.RoundingMode;46import java.text.spi.NumberFormatProvider;47import java.util.Currency;48import java.util.HashMap;49import java.util.Locale;50import java.util.Map;51import java.util.Objects;52import java.util.concurrent.atomic.AtomicInteger;53import java.util.concurrent.atomic.AtomicLong;54import sun.util.locale.provider.LocaleProviderAdapter;55import sun.util.locale.provider.LocaleServiceProviderPool;5657/**58* {@code NumberFormat} is the abstract base class for all number59* formats. This class provides the interface for formatting and parsing60* numbers. {@code NumberFormat} also provides methods for determining61* which locales have number formats, and what their names are.62*63* <p>64* {@code NumberFormat} helps you to format and parse numbers for any locale.65* Your code can be completely independent of the locale conventions for66* decimal points, thousands-separators, or even the particular decimal67* digits used, or whether the number format is even decimal.68*69* <p>70* To format a number for the current Locale, use one of the factory71* class methods:72* <blockquote>73* <pre>{@code74* myString = NumberFormat.getInstance().format(myNumber);75* }</pre>76* </blockquote>77* If you are formatting multiple numbers, it is78* more efficient to get the format and use it multiple times so that79* the system doesn't have to fetch the information about the local80* language and country conventions multiple times.81* <blockquote>82* <pre>{@code83* NumberFormat nf = NumberFormat.getInstance();84* for (int i = 0; i < myNumber.length; ++i) {85* output.println(nf.format(myNumber[i]) + "; ");86* }87* }</pre>88* </blockquote>89* To format a number for a different Locale, specify it in the90* call to {@code getInstance}.91* <blockquote>92* <pre>{@code93* NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);94* }</pre>95* </blockquote>96*97* <p>If the locale contains "nu" (numbers) and/or "rg" (region override)98* <a href="../util/Locale.html#def_locale_extension">Unicode extensions</a>,99* the decimal digits, and/or the country used for formatting are overridden.100* If both "nu" and "rg" are specified, the decimal digits from the "nu"101* extension supersedes the implicit one from the "rg" extension.102*103* <p>You can also use a {@code NumberFormat} to parse numbers:104* <blockquote>105* <pre>{@code106* myNumber = nf.parse(myString);107* }</pre>108* </blockquote>109* Use {@code getInstance} or {@code getNumberInstance} to get the110* normal number format. Use {@code getIntegerInstance} to get an111* integer number format. Use {@code getCurrencyInstance} to get the112* currency number format. Use {@code getCompactNumberInstance} to get the113* compact number format to format a number in shorter form. For example,114* {@code 2000} can be formatted as {@code "2K"} in115* {@link java.util.Locale#US US locale}. Use {@code getPercentInstance}116* to get a format for displaying percentages. With this format, a fraction117* like 0.53 is displayed as 53%.118*119* <p>120* You can also control the display of numbers with such methods as121* {@code setMinimumFractionDigits}.122* If you want even more control over the format or parsing,123* or want to give your users more control,124* you can try casting the {@code NumberFormat} you get from the factory methods125* to a {@code DecimalFormat} or {@code CompactNumberFormat} depending on126* the factory method used. This will work for the vast majority of locales;127* just remember to put it in a {@code try} block in case you encounter128* an unusual one.129*130* <p>131* NumberFormat and DecimalFormat are designed such that some controls132* work for formatting and others work for parsing. The following is133* the detailed description for each these control methods,134* <p>135* setParseIntegerOnly : only affects parsing, e.g.136* if true, "3456.78" → 3456 (and leaves the parse position just after index 6)137* if false, "3456.78" → 3456.78 (and leaves the parse position just after index 8)138* This is independent of formatting. If you want to not show a decimal point139* where there might be no digits after the decimal point, use140* setDecimalSeparatorAlwaysShown.141* <p>142* setDecimalSeparatorAlwaysShown : only affects formatting, and only where143* there might be no digits after the decimal point, such as with a pattern144* like "#,##0.##", e.g.,145* if true, 3456.00 → "3,456."146* if false, 3456.00 → "3456"147* This is independent of parsing. If you want parsing to stop at the decimal148* point, use setParseIntegerOnly.149*150* <p>151* You can also use forms of the {@code parse} and {@code format}152* methods with {@code ParsePosition} and {@code FieldPosition} to153* allow you to:154* <ul>155* <li> progressively parse through pieces of a string156* <li> align the decimal point and other areas157* </ul>158* For example, you can align numbers in two ways:159* <ol>160* <li> If you are using a monospaced font with spacing for alignment,161* you can pass the {@code FieldPosition} in your format call, with162* {@code field} = {@code INTEGER_FIELD}. On output,163* {@code getEndIndex} will be set to the offset between the164* last character of the integer and the decimal. Add165* (desiredSpaceCount - getEndIndex) spaces at the front of the string.166*167* <li> If you are using proportional fonts,168* instead of padding with spaces, measure the width169* of the string in pixels from the start to {@code getEndIndex}.170* Then move the pen by171* (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.172* It also works where there is no decimal, but possibly additional173* characters at the end, e.g., with parentheses in negative174* numbers: "(12)" for -12.175* </ol>176*177* <h2><a id="synchronization">Synchronization</a></h2>178*179* <p>180* Number formats are generally not synchronized.181* It is recommended to create separate format instances for each thread.182* If multiple threads access a format concurrently, it must be synchronized183* externally.184*185* @implSpec The {@link #format(double, StringBuffer, FieldPosition)},186* {@link #format(long, StringBuffer, FieldPosition)} and187* {@link #parse(String, ParsePosition)} methods may throw188* {@code NullPointerException}, if any of their parameter is {@code null}.189* The subclass may provide its own implementation and specification about190* {@code NullPointerException}.191*192* <p>193* The default implementation provides rounding modes defined194* in {@link java.math.RoundingMode} for formatting numbers. It195* uses the {@linkplain java.math.RoundingMode#HALF_EVEN196* round half-even algorithm}. To change the rounding mode use197* {@link #setRoundingMode(java.math.RoundingMode) setRoundingMode}.198* The {@code NumberFormat} returned by the static factory methods is199* configured to round floating point numbers using half-even200* rounding (see {@link java.math.RoundingMode#HALF_EVEN201* RoundingMode.HALF_EVEN}) for formatting.202*203* @see DecimalFormat204* @see ChoiceFormat205* @see CompactNumberFormat206* @author Mark Davis207* @author Helena Shih208* @since 1.1209*/210public abstract class NumberFormat extends Format {211212/**213* Field constant used to construct a FieldPosition object. Signifies that214* the position of the integer part of a formatted number should be returned.215* @see java.text.FieldPosition216*/217public static final int INTEGER_FIELD = 0;218219/**220* Field constant used to construct a FieldPosition object. Signifies that221* the position of the fraction part of a formatted number should be returned.222* @see java.text.FieldPosition223*/224public static final int FRACTION_FIELD = 1;225226/**227* Sole constructor. (For invocation by subclass constructors, typically228* implicit.)229*/230protected NumberFormat() {231}232233/**234* Formats a number and appends the resulting text to the given string235* buffer.236* The number can be of any subclass of {@link java.lang.Number}.237* <p>238* This implementation extracts the number's value using239* {@link java.lang.Number#longValue()} for all integral type values that240* can be converted to {@code long} without loss of information,241* including {@code BigInteger} values with a242* {@link java.math.BigInteger#bitLength() bit length} of less than 64,243* and {@link java.lang.Number#doubleValue()} for all other types. It244* then calls245* {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)}246* or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}.247* This may result in loss of magnitude information and precision for248* {@code BigInteger} and {@code BigDecimal} values.249* @param number the number to format250* @param toAppendTo the {@code StringBuffer} to which the formatted251* text is to be appended252* @param pos keeps track on the position of the field within the253* returned string. For example, for formatting a number254* {@code 1234567.89} in {@code Locale.US} locale,255* if the given {@code fieldPosition} is256* {@link NumberFormat#INTEGER_FIELD}, the begin index257* and end index of {@code fieldPosition} will be set258* to 0 and 9, respectively for the output string259* {@code 1,234,567.89}.260* @return the value passed in as {@code toAppendTo}261* @throws IllegalArgumentException if {@code number} is262* null or not an instance of {@code Number}.263* @throws NullPointerException if {@code toAppendTo} or264* {@code pos} is null265* @throws ArithmeticException if rounding is needed with rounding266* mode being set to RoundingMode.UNNECESSARY267* @see java.text.FieldPosition268*/269@Override270public StringBuffer format(Object number,271StringBuffer toAppendTo,272FieldPosition pos) {273if (number instanceof Long || number instanceof Integer ||274number instanceof Short || number instanceof Byte ||275number instanceof AtomicInteger || number instanceof AtomicLong ||276(number instanceof BigInteger &&277((BigInteger)number).bitLength() < 64)) {278return format(((Number)number).longValue(), toAppendTo, pos);279} else if (number instanceof Number) {280return format(((Number)number).doubleValue(), toAppendTo, pos);281} else {282throw new IllegalArgumentException("Cannot format given Object as a Number");283}284}285286/**287* Parses text from a string to produce a {@code Number}.288* <p>289* The method attempts to parse text starting at the index given by290* {@code pos}.291* If parsing succeeds, then the index of {@code pos} is updated292* to the index after the last character used (parsing does not necessarily293* use all characters up to the end of the string), and the parsed294* number is returned. The updated {@code pos} can be used to295* indicate the starting point for the next call to this method.296* If an error occurs, then the index of {@code pos} is not297* changed, the error index of {@code pos} is set to the index of298* the character where the error occurred, and null is returned.299* <p>300* See the {@link #parse(String, ParsePosition)} method for more information301* on number parsing.302*303* @param source A {@code String}, part of which should be parsed.304* @param pos A {@code ParsePosition} object with index and error305* index information as described above.306* @return A {@code Number} parsed from the string. In case of307* error, returns null.308* @throws NullPointerException if {@code source} or {@code pos} is null.309*/310@Override311public final Object parseObject(String source, ParsePosition pos) {312return parse(source, pos);313}314315/**316* Specialization of format.317*318* @param number the double number to format319* @return the formatted String320* @throws ArithmeticException if rounding is needed with rounding321* mode being set to RoundingMode.UNNECESSARY322* @see java.text.Format#format323*/324public final String format(double number) {325// Use fast-path for double result if that works326String result = fastFormat(number);327if (result != null)328return result;329330return format(number, new StringBuffer(),331DontCareFieldPosition.INSTANCE).toString();332}333334/*335* fastFormat() is supposed to be implemented in concrete subclasses only.336* Default implem always returns null.337*/338String fastFormat(double number) { return null; }339340/**341* Specialization of format.342*343* @param number the long number to format344* @return the formatted String345* @throws ArithmeticException if rounding is needed with rounding346* mode being set to RoundingMode.UNNECESSARY347* @see java.text.Format#format348*/349public final String format(long number) {350return format(number, new StringBuffer(),351DontCareFieldPosition.INSTANCE).toString();352}353354/**355* Specialization of format.356*357* @param number the double number to format358* @param toAppendTo the StringBuffer to which the formatted text is to be359* appended360* @param pos keeps track on the position of the field within the361* returned string. For example, for formatting a number362* {@code 1234567.89} in {@code Locale.US} locale,363* if the given {@code fieldPosition} is364* {@link NumberFormat#INTEGER_FIELD}, the begin index365* and end index of {@code fieldPosition} will be set366* to 0 and 9, respectively for the output string367* {@code 1,234,567.89}.368* @return the formatted StringBuffer369* @throws ArithmeticException if rounding is needed with rounding370* mode being set to RoundingMode.UNNECESSARY371* @see java.text.Format#format372*/373public abstract StringBuffer format(double number,374StringBuffer toAppendTo,375FieldPosition pos);376377/**378* Specialization of format.379*380* @param number the long number to format381* @param toAppendTo the StringBuffer to which the formatted text is to be382* appended383* @param pos keeps track on the position of the field within the384* returned string. For example, for formatting a number385* {@code 123456789} in {@code Locale.US} locale,386* if the given {@code fieldPosition} is387* {@link NumberFormat#INTEGER_FIELD}, the begin index388* and end index of {@code fieldPosition} will be set389* to 0 and 11, respectively for the output string390* {@code 123,456,789}.391* @return the formatted StringBuffer392* @throws ArithmeticException if rounding is needed with rounding393* mode being set to RoundingMode.UNNECESSARY394* @see java.text.Format#format395*/396public abstract StringBuffer format(long number,397StringBuffer toAppendTo,398FieldPosition pos);399400/**401* Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,402* Long.MAX_VALUE] and with no decimals), otherwise a Double.403* If IntegerOnly is set, will stop at a decimal404* point (or equivalent; e.g., for rational numbers "1 2/3", will stop405* after the 1).406* Does not throw an exception; if no object can be parsed, index is407* unchanged!408*409* @param source the String to parse410* @param parsePosition the parse position411* @return the parsed value412* @see java.text.NumberFormat#isParseIntegerOnly413* @see java.text.Format#parseObject414*/415public abstract Number parse(String source, ParsePosition parsePosition);416417/**418* Parses text from the beginning of the given string to produce a number.419* The method may not use the entire text of the given string.420* <p>421* See the {@link #parse(String, ParsePosition)} method for more information422* on number parsing.423*424* @param source A {@code String} whose beginning should be parsed.425* @return A {@code Number} parsed from the string.426* @throws ParseException if the beginning of the specified string427* cannot be parsed.428*/429public Number parse(String source) throws ParseException {430ParsePosition parsePosition = new ParsePosition(0);431Number result = parse(source, parsePosition);432if (parsePosition.index == 0) {433throw new ParseException("Unparseable number: \"" + source + "\"",434parsePosition.errorIndex);435}436return result;437}438439/**440* Returns true if this format will parse numbers as integers only.441* For example in the English locale, with ParseIntegerOnly true, the442* string "1234." would be parsed as the integer value 1234 and parsing443* would stop at the "." character. Of course, the exact format accepted444* by the parse operation is locale dependent and determined by sub-classes445* of NumberFormat.446*447* @return {@code true} if numbers should be parsed as integers only;448* {@code false} otherwise449*/450public boolean isParseIntegerOnly() {451return parseIntegerOnly;452}453454/**455* Sets whether or not numbers should be parsed as integers only.456*457* @param value {@code true} if numbers should be parsed as integers only;458* {@code false} otherwise459* @see #isParseIntegerOnly460*/461public void setParseIntegerOnly(boolean value) {462parseIntegerOnly = value;463}464465//============== Locale Stuff =====================466467/**468* Returns a general-purpose number format for the current default469* {@link java.util.Locale.Category#FORMAT FORMAT} locale.470* This is the same as calling471* {@link #getNumberInstance() getNumberInstance()}.472*473* @return the {@code NumberFormat} instance for general-purpose number474* formatting475*/476public static final NumberFormat getInstance() {477return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, NUMBERSTYLE);478}479480/**481* Returns a general-purpose number format for the specified locale.482* This is the same as calling483* {@link #getNumberInstance(java.util.Locale) getNumberInstance(inLocale)}.484*485* @param inLocale the desired locale486* @return the {@code NumberFormat} instance for general-purpose number487* formatting488*/489public static NumberFormat getInstance(Locale inLocale) {490return getInstance(inLocale, null, NUMBERSTYLE);491}492493/**494* Returns a general-purpose number format for the current default495* {@link java.util.Locale.Category#FORMAT FORMAT} locale.496* <p>This is equivalent to calling497* {@link #getNumberInstance(Locale)498* getNumberInstance(Locale.getDefault(Locale.Category.FORMAT))}.499*500* @return the {@code NumberFormat} instance for general-purpose number501* formatting502* @see java.util.Locale#getDefault(java.util.Locale.Category)503* @see java.util.Locale.Category#FORMAT504*/505public static final NumberFormat getNumberInstance() {506return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, NUMBERSTYLE);507}508509/**510* Returns a general-purpose number format for the specified locale.511*512* @param inLocale the desired locale513* @return the {@code NumberFormat} instance for general-purpose number514* formatting515*/516public static NumberFormat getNumberInstance(Locale inLocale) {517return getInstance(inLocale, null, NUMBERSTYLE);518}519520/**521* Returns an integer number format for the current default522* {@link java.util.Locale.Category#FORMAT FORMAT} locale. The523* returned number format is configured to round floating point numbers524* to the nearest integer using half-even rounding (see {@link525* java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,526* and to parse only the integer part of an input string (see {@link527* #isParseIntegerOnly isParseIntegerOnly}).528* <p>This is equivalent to calling529* {@link #getIntegerInstance(Locale)530* getIntegerInstance(Locale.getDefault(Locale.Category.FORMAT))}.531*532* @see #getRoundingMode()533* @see java.util.Locale#getDefault(java.util.Locale.Category)534* @see java.util.Locale.Category#FORMAT535* @return a number format for integer values536* @since 1.4537*/538public static final NumberFormat getIntegerInstance() {539return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, INTEGERSTYLE);540}541542/**543* Returns an integer number format for the specified locale. The544* returned number format is configured to round floating point numbers545* to the nearest integer using half-even rounding (see {@link546* java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,547* and to parse only the integer part of an input string (see {@link548* #isParseIntegerOnly isParseIntegerOnly}).549*550* @param inLocale the desired locale551* @see #getRoundingMode()552* @return a number format for integer values553* @since 1.4554*/555public static NumberFormat getIntegerInstance(Locale inLocale) {556return getInstance(inLocale, null, INTEGERSTYLE);557}558559/**560* Returns a currency format for the current default561* {@link java.util.Locale.Category#FORMAT FORMAT} locale.562* <p>This is equivalent to calling563* {@link #getCurrencyInstance(Locale)564* getCurrencyInstance(Locale.getDefault(Locale.Category.FORMAT))}.565*566* @return the {@code NumberFormat} instance for currency formatting567* @see java.util.Locale#getDefault(java.util.Locale.Category)568* @see java.util.Locale.Category#FORMAT569*/570public static final NumberFormat getCurrencyInstance() {571return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, CURRENCYSTYLE);572}573574/**575* Returns a currency format for the specified locale.576*577* <p>If the specified locale contains the "{@code cf}" (578* <a href="https://www.unicode.org/reports/tr35/tr35.html#UnicodeCurrencyFormatIdentifier">579* currency format style</a>)580* <a href="../util/Locale.html#def_locale_extension">Unicode extension</a>,581* the returned currency format uses the style if it is available.582* Otherwise, the style uses the default "{@code standard}" currency format.583* For example, if the style designates "{@code account}", negative584* currency amounts use a pair of parentheses in some locales.585*586* @param inLocale the desired locale587* @return the {@code NumberFormat} instance for currency formatting588*/589public static NumberFormat getCurrencyInstance(Locale inLocale) {590return getInstance(inLocale, null, CURRENCYSTYLE);591}592593/**594* Returns a percentage format for the current default595* {@link java.util.Locale.Category#FORMAT FORMAT} locale.596* <p>This is equivalent to calling597* {@link #getPercentInstance(Locale)598* getPercentInstance(Locale.getDefault(Locale.Category.FORMAT))}.599*600* @return the {@code NumberFormat} instance for percentage formatting601* @see java.util.Locale#getDefault(java.util.Locale.Category)602* @see java.util.Locale.Category#FORMAT603*/604public static final NumberFormat getPercentInstance() {605return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, PERCENTSTYLE);606}607608/**609* Returns a percentage format for the specified locale.610*611* @param inLocale the desired locale612* @return the {@code NumberFormat} instance for percentage formatting613*/614public static NumberFormat getPercentInstance(Locale inLocale) {615return getInstance(inLocale, null, PERCENTSTYLE);616}617618/**619* Returns a scientific format for the current default locale.620*/621/*public*/ static final NumberFormat getScientificInstance() {622return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, SCIENTIFICSTYLE);623}624625/**626* Returns a scientific format for the specified locale.627*628* @param inLocale the desired locale629*/630/*public*/ static NumberFormat getScientificInstance(Locale inLocale) {631return getInstance(inLocale, null, SCIENTIFICSTYLE);632}633634/**635* Returns a compact number format for the default636* {@link java.util.Locale.Category#FORMAT FORMAT} locale with637* {@link NumberFormat.Style#SHORT "SHORT"} format style.638*639* @return A {@code NumberFormat} instance for compact number640* formatting641*642* @see CompactNumberFormat643* @see NumberFormat.Style644* @see java.util.Locale#getDefault(java.util.Locale.Category)645* @see java.util.Locale.Category#FORMAT646* @since 12647*/648public static NumberFormat getCompactNumberInstance() {649return getInstance(Locale.getDefault(650Locale.Category.FORMAT), NumberFormat.Style.SHORT, COMPACTSTYLE);651}652653/**654* Returns a compact number format for the specified {@link java.util.Locale locale}655* and {@link NumberFormat.Style formatStyle}.656*657* @param locale the desired locale658* @param formatStyle the style for formatting a number659* @return A {@code NumberFormat} instance for compact number660* formatting661* @throws NullPointerException if {@code locale} or {@code formatStyle}662* is {@code null}663*664* @see CompactNumberFormat665* @see NumberFormat.Style666* @see java.util.Locale667* @since 12668*/669public static NumberFormat getCompactNumberInstance(Locale locale,670NumberFormat.Style formatStyle) {671672Objects.requireNonNull(locale);673Objects.requireNonNull(formatStyle);674return getInstance(locale, formatStyle, COMPACTSTYLE);675}676677/**678* Returns an array of all locales for which the679* {@code get*Instance} methods of this class can return680* localized instances.681* The returned array represents the union of locales supported by the Java682* runtime and by installed683* {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations.684* It must contain at least a {@code Locale} instance equal to685* {@link java.util.Locale#US Locale.US}.686*687* @return An array of locales for which localized688* {@code NumberFormat} instances are available.689*/690public static Locale[] getAvailableLocales() {691LocaleServiceProviderPool pool =692LocaleServiceProviderPool.getPool(NumberFormatProvider.class);693return pool.getAvailableLocales();694}695696/**697* Overrides hashCode.698*/699@Override700public int hashCode() {701return maximumIntegerDigits * 37 + maxFractionDigits;702// just enough fields for a reasonable distribution703}704705/**706* Overrides equals.707*/708@Override709public boolean equals(Object obj) {710if (obj == null) {711return false;712}713if (this == obj) {714return true;715}716if (getClass() != obj.getClass()) {717return false;718}719NumberFormat other = (NumberFormat) obj;720return (maximumIntegerDigits == other.maximumIntegerDigits721&& minimumIntegerDigits == other.minimumIntegerDigits722&& maximumFractionDigits == other.maximumFractionDigits723&& minimumFractionDigits == other.minimumFractionDigits724&& groupingUsed == other.groupingUsed725&& parseIntegerOnly == other.parseIntegerOnly);726}727728/**729* Overrides Cloneable.730*/731@Override732public Object clone() {733NumberFormat other = (NumberFormat) super.clone();734return other;735}736737/**738* Returns true if grouping is used in this format. For example, in the739* English locale, with grouping on, the number 1234567 might be formatted740* as "1,234,567". The grouping separator as well as the size of each group741* is locale dependent and is determined by sub-classes of NumberFormat.742*743* @return {@code true} if grouping is used;744* {@code false} otherwise745* @see #setGroupingUsed746*/747public boolean isGroupingUsed() {748return groupingUsed;749}750751/**752* Set whether or not grouping will be used in this format.753*754* @param newValue {@code true} if grouping is used;755* {@code false} otherwise756* @see #isGroupingUsed757*/758public void setGroupingUsed(boolean newValue) {759groupingUsed = newValue;760}761762/**763* Returns the maximum number of digits allowed in the integer portion of a764* number.765*766* @return the maximum number of digits767* @see #setMaximumIntegerDigits768*/769public int getMaximumIntegerDigits() {770return maximumIntegerDigits;771}772773/**774* Sets the maximum number of digits allowed in the integer portion of a775* number. maximumIntegerDigits must be ≥ minimumIntegerDigits. If the776* new value for maximumIntegerDigits is less than the current value777* of minimumIntegerDigits, then minimumIntegerDigits will also be set to778* the new value.779*780* @param newValue the maximum number of integer digits to be shown; if781* less than zero, then zero is used. The concrete subclass may enforce an782* upper limit to this value appropriate to the numeric type being formatted.783* @see #getMaximumIntegerDigits784*/785public void setMaximumIntegerDigits(int newValue) {786maximumIntegerDigits = Math.max(0,newValue);787if (minimumIntegerDigits > maximumIntegerDigits) {788minimumIntegerDigits = maximumIntegerDigits;789}790}791792/**793* Returns the minimum number of digits allowed in the integer portion of a794* number.795*796* @return the minimum number of digits797* @see #setMinimumIntegerDigits798*/799public int getMinimumIntegerDigits() {800return minimumIntegerDigits;801}802803/**804* Sets the minimum number of digits allowed in the integer portion of a805* number. minimumIntegerDigits must be ≤ maximumIntegerDigits. If the806* new value for minimumIntegerDigits exceeds the current value807* of maximumIntegerDigits, then maximumIntegerDigits will also be set to808* the new value809*810* @param newValue the minimum number of integer digits to be shown; if811* less than zero, then zero is used. The concrete subclass may enforce an812* upper limit to this value appropriate to the numeric type being formatted.813* @see #getMinimumIntegerDigits814*/815public void setMinimumIntegerDigits(int newValue) {816minimumIntegerDigits = Math.max(0,newValue);817if (minimumIntegerDigits > maximumIntegerDigits) {818maximumIntegerDigits = minimumIntegerDigits;819}820}821822/**823* Returns the maximum number of digits allowed in the fraction portion of a824* number.825*826* @return the maximum number of digits.827* @see #setMaximumFractionDigits828*/829public int getMaximumFractionDigits() {830return maximumFractionDigits;831}832833/**834* Sets the maximum number of digits allowed in the fraction portion of a835* number. maximumFractionDigits must be ≥ minimumFractionDigits. If the836* new value for maximumFractionDigits is less than the current value837* of minimumFractionDigits, then minimumFractionDigits will also be set to838* the new value.839*840* @param newValue the maximum number of fraction digits to be shown; if841* less than zero, then zero is used. The concrete subclass may enforce an842* upper limit to this value appropriate to the numeric type being formatted.843* @see #getMaximumFractionDigits844*/845public void setMaximumFractionDigits(int newValue) {846maximumFractionDigits = Math.max(0,newValue);847if (maximumFractionDigits < minimumFractionDigits) {848minimumFractionDigits = maximumFractionDigits;849}850}851852/**853* Returns the minimum number of digits allowed in the fraction portion of a854* number.855*856* @return the minimum number of digits857* @see #setMinimumFractionDigits858*/859public int getMinimumFractionDigits() {860return minimumFractionDigits;861}862863/**864* Sets the minimum number of digits allowed in the fraction portion of a865* number. minimumFractionDigits must be ≤ maximumFractionDigits. If the866* new value for minimumFractionDigits exceeds the current value867* of maximumFractionDigits, then maximumFractionDigits will also be set to868* the new value869*870* @param newValue the minimum number of fraction digits to be shown; if871* less than zero, then zero is used. The concrete subclass may enforce an872* upper limit to this value appropriate to the numeric type being formatted.873* @see #getMinimumFractionDigits874*/875public void setMinimumFractionDigits(int newValue) {876minimumFractionDigits = Math.max(0,newValue);877if (maximumFractionDigits < minimumFractionDigits) {878maximumFractionDigits = minimumFractionDigits;879}880}881882/**883* Gets the currency used by this number format when formatting884* currency values. The initial value is derived in a locale dependent885* way. The returned value may be null if no valid886* currency could be determined and no currency has been set using887* {@link #setCurrency(java.util.Currency) setCurrency}.888* <p>889* The default implementation throws890* {@code UnsupportedOperationException}.891*892* @return the currency used by this number format, or {@code null}893* @throws UnsupportedOperationException if the number format class894* doesn't implement currency formatting895* @since 1.4896*/897public Currency getCurrency() {898throw new UnsupportedOperationException();899}900901/**902* Sets the currency used by this number format when formatting903* currency values. This does not update the minimum or maximum904* number of fraction digits used by the number format.905* <p>906* The default implementation throws907* {@code UnsupportedOperationException}.908*909* @param currency the new currency to be used by this number format910* @throws UnsupportedOperationException if the number format class911* doesn't implement currency formatting912* @throws NullPointerException if {@code currency} is null913* @since 1.4914*/915public void setCurrency(Currency currency) {916throw new UnsupportedOperationException();917}918919/**920* Gets the {@link java.math.RoundingMode} used in this NumberFormat.921* The default implementation of this method in NumberFormat922* always throws {@link java.lang.UnsupportedOperationException}.923* Subclasses which handle different rounding modes should override924* this method.925*926* @throws UnsupportedOperationException The default implementation927* always throws this exception928* @return The {@code RoundingMode} used for this NumberFormat.929* @see #setRoundingMode(RoundingMode)930* @since 1.6931*/932public RoundingMode getRoundingMode() {933throw new UnsupportedOperationException();934}935936/**937* Sets the {@link java.math.RoundingMode} used in this NumberFormat.938* The default implementation of this method in NumberFormat always939* throws {@link java.lang.UnsupportedOperationException}.940* Subclasses which handle different rounding modes should override941* this method.942*943* @throws UnsupportedOperationException The default implementation944* always throws this exception945* @throws NullPointerException if {@code roundingMode} is null946* @param roundingMode The {@code RoundingMode} to be used947* @see #getRoundingMode()948* @since 1.6949*/950public void setRoundingMode(RoundingMode roundingMode) {951throw new UnsupportedOperationException();952}953954// =======================privates===============================955956private static NumberFormat getInstance(Locale desiredLocale,957Style formatStyle, int choice) {958LocaleProviderAdapter adapter;959adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class,960desiredLocale);961NumberFormat numberFormat = getInstance(adapter, desiredLocale,962formatStyle, choice);963if (numberFormat == null) {964numberFormat = getInstance(LocaleProviderAdapter.forJRE(),965desiredLocale, formatStyle, choice);966}967return numberFormat;968}969970private static NumberFormat getInstance(LocaleProviderAdapter adapter,971Locale locale, Style formatStyle,972int choice) {973NumberFormatProvider provider = adapter.getNumberFormatProvider();974return switch (choice) {975case NUMBERSTYLE -> provider.getNumberInstance(locale);976case PERCENTSTYLE -> provider.getPercentInstance(locale);977case CURRENCYSTYLE -> provider.getCurrencyInstance(locale);978case INTEGERSTYLE -> provider.getIntegerInstance(locale);979case COMPACTSTYLE -> provider.getCompactNumberInstance(locale, formatStyle);980default -> null;981};982}983984/**985* First, read in the default serializable data.986*987* Then, if {@code serialVersionOnStream} is less than 1, indicating that988* the stream was written by JDK 1.1,989* set the {@code int} fields such as {@code maximumIntegerDigits}990* to be equal to the {@code byte} fields such as {@code maxIntegerDigits},991* since the {@code int} fields were not present in JDK 1.1.992* Finally, set serialVersionOnStream back to the maximum allowed value so that993* default serialization will work properly if this object is streamed out again.994*995* <p>If {@code minimumIntegerDigits} is greater than996* {@code maximumIntegerDigits} or {@code minimumFractionDigits}997* is greater than {@code maximumFractionDigits}, then the stream data998* is invalid and this method throws an {@code InvalidObjectException}.999* In addition, if any of these values is negative, then this method throws1000* an {@code InvalidObjectException}.1001*1002* @since 1.21003*/1004@java.io.Serial1005private void readObject(ObjectInputStream stream)1006throws IOException, ClassNotFoundException1007{1008stream.defaultReadObject();1009if (serialVersionOnStream < 1) {1010// Didn't have additional int fields, reassign to use them.1011maximumIntegerDigits = maxIntegerDigits;1012minimumIntegerDigits = minIntegerDigits;1013maximumFractionDigits = maxFractionDigits;1014minimumFractionDigits = minFractionDigits;1015}1016if (minimumIntegerDigits > maximumIntegerDigits ||1017minimumFractionDigits > maximumFractionDigits ||1018minimumIntegerDigits < 0 || minimumFractionDigits < 0) {1019throw new InvalidObjectException("Digit count range invalid");1020}1021serialVersionOnStream = currentSerialVersion;1022}10231024/**1025* Write out the default serializable data, after first setting1026* the {@code byte} fields such as {@code maxIntegerDigits} to be1027* equal to the {@code int} fields such as {@code maximumIntegerDigits}1028* (or to {@code Byte.MAX_VALUE}, whichever is smaller), for compatibility1029* with the JDK 1.1 version of the stream format.1030*1031* @since 1.21032*/1033@java.io.Serial1034private void writeObject(ObjectOutputStream stream)1035throws IOException1036{1037maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ?1038Byte.MAX_VALUE : (byte)maximumIntegerDigits;1039minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ?1040Byte.MAX_VALUE : (byte)minimumIntegerDigits;1041maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ?1042Byte.MAX_VALUE : (byte)maximumFractionDigits;1043minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ?1044Byte.MAX_VALUE : (byte)minimumFractionDigits;1045stream.defaultWriteObject();1046}10471048// Constants used by factory methods to specify a style of format.1049private static final int NUMBERSTYLE = 0;1050private static final int CURRENCYSTYLE = 1;1051private static final int PERCENTSTYLE = 2;1052private static final int SCIENTIFICSTYLE = 3;1053private static final int INTEGERSTYLE = 4;1054private static final int COMPACTSTYLE = 5;10551056/**1057* True if the grouping (i.e. thousands) separator is used when1058* formatting and parsing numbers.1059*1060* @serial1061* @see #isGroupingUsed1062*/1063private boolean groupingUsed = true;10641065/**1066* The maximum number of digits allowed in the integer portion of a1067* number. {@code maxIntegerDigits} must be greater than or equal to1068* {@code minIntegerDigits}.1069* <p>1070* <strong>Note:</strong> This field exists only for serialization1071* compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new1072* {@code int} field {@code maximumIntegerDigits} is used instead.1073* When writing to a stream, {@code maxIntegerDigits} is set to1074* {@code maximumIntegerDigits} or {@code Byte.MAX_VALUE},1075* whichever is smaller. When reading from a stream, this field is used1076* only if {@code serialVersionOnStream} is less than 1.1077*1078* @serial1079* @see #getMaximumIntegerDigits1080*/1081private byte maxIntegerDigits = 40;10821083/**1084* The minimum number of digits allowed in the integer portion of a1085* number. {@code minimumIntegerDigits} must be less than or equal to1086* {@code maximumIntegerDigits}.1087* <p>1088* <strong>Note:</strong> This field exists only for serialization1089* compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new1090* {@code int} field {@code minimumIntegerDigits} is used instead.1091* When writing to a stream, {@code minIntegerDigits} is set to1092* {@code minimumIntegerDigits} or {@code Byte.MAX_VALUE},1093* whichever is smaller. When reading from a stream, this field is used1094* only if {@code serialVersionOnStream} is less than 1.1095*1096* @serial1097* @see #getMinimumIntegerDigits1098*/1099private byte minIntegerDigits = 1;11001101/**1102* The maximum number of digits allowed in the fractional portion of a1103* number. {@code maximumFractionDigits} must be greater than or equal to1104* {@code minimumFractionDigits}.1105* <p>1106* <strong>Note:</strong> This field exists only for serialization1107* compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new1108* {@code int} field {@code maximumFractionDigits} is used instead.1109* When writing to a stream, {@code maxFractionDigits} is set to1110* {@code maximumFractionDigits} or {@code Byte.MAX_VALUE},1111* whichever is smaller. When reading from a stream, this field is used1112* only if {@code serialVersionOnStream} is less than 1.1113*1114* @serial1115* @see #getMaximumFractionDigits1116*/1117private byte maxFractionDigits = 3; // invariant, >= minFractionDigits11181119/**1120* The minimum number of digits allowed in the fractional portion of a1121* number. {@code minimumFractionDigits} must be less than or equal to1122* {@code maximumFractionDigits}.1123* <p>1124* <strong>Note:</strong> This field exists only for serialization1125* compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new1126* {@code int} field {@code minimumFractionDigits} is used instead.1127* When writing to a stream, {@code minFractionDigits} is set to1128* {@code minimumFractionDigits} or {@code Byte.MAX_VALUE},1129* whichever is smaller. When reading from a stream, this field is used1130* only if {@code serialVersionOnStream} is less than 1.1131*1132* @serial1133* @see #getMinimumFractionDigits1134*/1135private byte minFractionDigits = 0;11361137/**1138* True if this format will parse numbers as integers only.1139*1140* @serial1141* @see #isParseIntegerOnly1142*/1143private boolean parseIntegerOnly = false;11441145// new fields for 1.2. byte is too small for integer digits.11461147/**1148* The maximum number of digits allowed in the integer portion of a1149* number. {@code maximumIntegerDigits} must be greater than or equal to1150* {@code minimumIntegerDigits}.1151*1152* @serial1153* @since 1.21154* @see #getMaximumIntegerDigits1155*/1156private int maximumIntegerDigits = 40;11571158/**1159* The minimum number of digits allowed in the integer portion of a1160* number. {@code minimumIntegerDigits} must be less than or equal to1161* {@code maximumIntegerDigits}.1162*1163* @serial1164* @since 1.21165* @see #getMinimumIntegerDigits1166*/1167private int minimumIntegerDigits = 1;11681169/**1170* The maximum number of digits allowed in the fractional portion of a1171* number. {@code maximumFractionDigits} must be greater than or equal to1172* {@code minimumFractionDigits}.1173*1174* @serial1175* @since 1.21176* @see #getMaximumFractionDigits1177*/1178private int maximumFractionDigits = 3; // invariant, >= minFractionDigits11791180/**1181* The minimum number of digits allowed in the fractional portion of a1182* number. {@code minimumFractionDigits} must be less than or equal to1183* {@code maximumFractionDigits}.1184*1185* @serial1186* @since 1.21187* @see #getMinimumFractionDigits1188*/1189private int minimumFractionDigits = 0;11901191static final int currentSerialVersion = 1;11921193/**1194* Describes the version of {@code NumberFormat} present on the stream.1195* Possible values are:1196* <ul>1197* <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.1198* In this version, the {@code int} fields such as1199* {@code maximumIntegerDigits} were not present, and the {@code byte}1200* fields such as {@code maxIntegerDigits} are used instead.1201*1202* <li><b>1</b>: the 1.2 version of the stream format. The values of the1203* {@code byte} fields such as {@code maxIntegerDigits} are ignored,1204* and the {@code int} fields such as {@code maximumIntegerDigits}1205* are used instead.1206* </ul>1207* When streaming out a {@code NumberFormat}, the most recent format1208* (corresponding to the highest allowable {@code serialVersionOnStream})1209* is always written.1210*1211* @serial1212* @since 1.21213*/1214private int serialVersionOnStream = currentSerialVersion;12151216// Removed "implements Cloneable" clause. Needs to update serialization1217// ID for backward compatibility.1218@java.io.Serial1219static final long serialVersionUID = -2308460125733713944L;122012211222//1223// class for AttributedCharacterIterator attributes1224//1225/**1226* Defines constants that are used as attribute keys in the1227* {@code AttributedCharacterIterator} returned1228* from {@code NumberFormat.formatToCharacterIterator} and as1229* field identifiers in {@code FieldPosition}.1230*1231* @since 1.41232*/1233public static class Field extends Format.Field {12341235// Proclaim serial compatibility with 1.4 FCS1236@java.io.Serial1237private static final long serialVersionUID = 7494728892700160890L;12381239// table of all instances in this class, used by readResolve1240private static final Map<String, Field> instanceMap = new HashMap<>(11);12411242/**1243* Creates a Field instance with the specified1244* name.1245*1246* @param name Name of the attribute1247*/1248protected Field(String name) {1249super(name);1250if (this.getClass() == NumberFormat.Field.class) {1251instanceMap.put(name, this);1252}1253}12541255/**1256* Resolves instances being deserialized to the predefined constants.1257*1258* @throws InvalidObjectException if the constant could not be resolved.1259* @return resolved NumberFormat.Field constant1260*/1261@Override1262@java.io.Serial1263protected Object readResolve() throws InvalidObjectException {1264if (this.getClass() != NumberFormat.Field.class) {1265throw new InvalidObjectException("subclass didn't correctly implement readResolve");1266}12671268Object instance = instanceMap.get(getName());1269if (instance != null) {1270return instance;1271} else {1272throw new InvalidObjectException("unknown attribute name");1273}1274}12751276/**1277* Constant identifying the integer field.1278*/1279public static final Field INTEGER = new Field("integer");12801281/**1282* Constant identifying the fraction field.1283*/1284public static final Field FRACTION = new Field("fraction");12851286/**1287* Constant identifying the exponent field.1288*/1289public static final Field EXPONENT = new Field("exponent");12901291/**1292* Constant identifying the decimal separator field.1293*/1294public static final Field DECIMAL_SEPARATOR =1295new Field("decimal separator");12961297/**1298* Constant identifying the sign field.1299*/1300public static final Field SIGN = new Field("sign");13011302/**1303* Constant identifying the grouping separator field.1304*/1305public static final Field GROUPING_SEPARATOR =1306new Field("grouping separator");13071308/**1309* Constant identifying the exponent symbol field.1310*/1311public static final Field EXPONENT_SYMBOL = new1312Field("exponent symbol");13131314/**1315* Constant identifying the percent field.1316*/1317public static final Field PERCENT = new Field("percent");13181319/**1320* Constant identifying the permille field.1321*/1322public static final Field PERMILLE = new Field("per mille");13231324/**1325* Constant identifying the currency field.1326*/1327public static final Field CURRENCY = new Field("currency");13281329/**1330* Constant identifying the exponent sign field.1331*/1332public static final Field EXPONENT_SIGN = new Field("exponent sign");13331334/**1335* Constant identifying the prefix field.1336*1337* @since 121338*/1339public static final Field PREFIX = new Field("prefix");13401341/**1342* Constant identifying the suffix field.1343*1344* @since 121345*/1346public static final Field SUFFIX = new Field("suffix");1347}13481349/**1350* A number format style.1351* <p>1352* {@code Style} is an enum which represents the style for formatting1353* a number within a given {@code NumberFormat} instance.1354*1355* @see CompactNumberFormat1356* @see NumberFormat#getCompactNumberInstance(Locale, Style)1357* @since 121358*/1359public enum Style {13601361/**1362* The {@code SHORT} number format style.1363*/1364SHORT,13651366/**1367* The {@code LONG} number format style.1368*/1369LONG13701371}1372}137313741375