/** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************//** (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved** The original version of this source code and documentation is copyrighted* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These* materials are provided under terms of a License Agreement between Taligent* and Sun. This technology is protected by multiple US and International* patents. This notice and attribution to Taligent may not be removed.* Taligent is a registered trademark of Taligent, Inc.**/package java.text;import java.io.InvalidObjectException;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.math.BigInteger;import java.math.RoundingMode;import java.text.spi.NumberFormatProvider;import java.util.Currency;import java.util.HashMap;import java.util.Hashtable;import java.util.Locale;import java.util.Map;import java.util.ResourceBundle;import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.atomic.AtomicLong;import java.util.spi.LocaleServiceProvider;import sun.util.locale.provider.LocaleProviderAdapter;import sun.util.locale.provider.LocaleServiceProviderPool;/*** <code>NumberFormat</code> is the abstract base class for all number* formats. This class provides the interface for formatting and parsing* numbers. <code>NumberFormat</code> also provides methods for determining* which locales have number formats, and what their names are.** <p>* <code>NumberFormat</code> helps you to format and parse numbers for any locale.* Your code can be completely independent of the locale conventions for* decimal points, thousands-separators, or even the particular decimal* digits used, or whether the number format is even decimal.** <p>* To format a number for the current Locale, use one of the factory* class methods:* <blockquote>* <pre>{@code* myString = NumberFormat.getInstance().format(myNumber);* }</pre>* </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>* <pre>{@code* NumberFormat nf = NumberFormat.getInstance();* for (int i = 0; i < myNumber.length; ++i) {* output.println(nf.format(myNumber[i]) + "; ");* }* }</pre>* </blockquote>* To format a number for a different Locale, specify it in the* call to <code>getInstance</code>.* <blockquote>* <pre>{@code* NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);* }</pre>* </blockquote>** <p>If the locale contains "nu" (numbers) and/or "rg" (region override)* <a href="../util/Locale.html#def_locale_extension">Unicode extensions</a>,* the decimal digits, and/or the country used for formatting are overridden.* If both "nu" and "rg" are specified, the decimal digits from the "nu"* extension supersedes the implicit one from the "rg" extension.** <p>You can also use a {@code NumberFormat} to parse numbers:* <blockquote>* <pre>{@code* myNumber = nf.parse(myString);* }</pre>* </blockquote>* Use <code>getInstance</code> or <code>getNumberInstance</code> to get the* normal number format. Use <code>getIntegerInstance</code> to get an* integer number format. Use <code>getCurrencyInstance</code> to get the* currency number format. And use <code>getPercentInstance</code> to get a* format for displaying percentages. With this format, a fraction like* 0.53 is displayed as 53%.** <p>* You can also control the display of numbers with such methods as* <code>setMinimumFractionDigits</code>.* If you want even more control over the format or parsing,* or want to give your users more control,* you can try casting the <code>NumberFormat</code> you get from the factory methods* to a <code>DecimalFormat</code>. This will work for the vast majority* of locales; just remember to put it in a <code>try</code> block in case you* encounter an unusual one.** <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" → 3456 (and leaves the parse position just after index 6)* if false, "3456.78" → 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 → "3,456."* if false, 3456.00 → "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</code> and <code>format</code>* methods with <code>ParsePosition</code> and <code>FieldPosition</code> to* allow you to:* <ul>* <li> progressively parse through pieces of a string* <li> align the decimal point and other areas* </ul>* For example, you can align numbers in two ways:* <ol>* <li> If you are using a monospaced font with spacing for alignment,* you can pass the <code>FieldPosition</code> in your format call, with* <code>field</code> = <code>INTEGER_FIELD</code>. On output,* <code>getEndIndex</code> will be set to the offset between the* last character of the integer and the decimal. Add* (desiredSpaceCount - getEndIndex) spaces at the front of the string.** <li> If you are using proportional fonts,* instead of padding with spaces, measure the width* of the string in pixels from the start to <code>getEndIndex</code>.* Then move the pen by* (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.* It also works where there is no decimal, but possibly additional* characters at the end, e.g., with parentheses in negative* numbers: "(12)" for -12.* </ol>** <h3><a id="synchronization">Synchronization</a></h3>** <p>* Number 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.** @implSpec The {@link #format(double, StringBuffer, FieldPosition)},* {@link #format(long, StringBuffer, FieldPosition)} and* {@link #parse(String, ParsePosition)} methods may throw* {@code NullPointerException}, if any of their parameter is {@code null}.* The subclass may provide its own implementation and specification about* {@code NullPointerException}.** <p>* The default implementation provides rounding modes defined* in {@link java.math.RoundingMode} for formatting numbers. It* uses the {@linkplain java.math.RoundingMode#HALF_EVEN* round half-even algorithm}. To change the rounding mode use* {@link #setRoundingMode(java.math.RoundingMode) setRoundingMode}.* The {@code NumberFormat} returned by the static factory methods is* configured to round floating point numbers using half-even* rounding (see {@link java.math.RoundingMode#HALF_EVEN* RoundingMode.HALF_EVEN}) for formatting.** @see DecimalFormat* @see ChoiceFormat* @author Mark Davis* @author Helena Shih* @since 1.1*/public abstract class NumberFormat extends Format {/*** Field constant used to construct a FieldPosition object. Signifies that* the position of the integer part of a formatted number should be returned.* @see java.text.FieldPosition*/public static final int INTEGER_FIELD = 0;/*** Field constant used to construct a FieldPosition object. Signifies that* the position of the fraction part of a formatted number should be returned.* @see java.text.FieldPosition*/public static final int FRACTION_FIELD = 1;/*** Sole constructor. (For invocation by subclass constructors, typically* implicit.)*/protected NumberFormat() {}/*** Formats a number and appends the resulting text to the given string* buffer.* The number can be of any subclass of {@link java.lang.Number}.* <p>* This implementation extracts the number's value using* {@link java.lang.Number#longValue()} for all integral type values that* can be converted to <code>long</code> without loss of information,* including <code>BigInteger</code> values with a* {@link java.math.BigInteger#bitLength() bit length} of less than 64,* and {@link java.lang.Number#doubleValue()} for all other types. It* then calls* {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)}* or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}.* This may result in loss of magnitude information and precision for* <code>BigInteger</code> and <code>BigDecimal</code> values.* @param number the number to format* @param toAppendTo the <code>StringBuffer</code> to which the formatted* text is to be appended* @param pos keeps track on the position of the field within the* returned string. For example, for formatting a number* {@code 1234567.89} in {@code Locale.US} locale,* if the given {@code fieldPosition} is* {@link NumberFormat#INTEGER_FIELD}, the begin index* and end index of {@code fieldPosition} will be set* to 0 and 9, respectively for the output string* {@code 1,234,567.89}.* @return the value passed in as <code>toAppendTo</code>* @exception IllegalArgumentException if <code>number</code> is* null or not an instance of <code>Number</code>.* @exception NullPointerException if <code>toAppendTo</code> or* <code>pos</code> is null* @exception ArithmeticException if rounding is needed with rounding* mode being set to RoundingMode.UNNECESSARY* @see java.text.FieldPosition*/@Overridepublic StringBuffer format(Object number,StringBuffer toAppendTo,FieldPosition pos) {if (number instanceof Long || number instanceof Integer ||number instanceof Short || number instanceof Byte ||number instanceof AtomicInteger || number instanceof AtomicLong ||(number instanceof BigInteger &&((BigInteger)number).bitLength() < 64)) {return format(((Number)number).longValue(), toAppendTo, pos);} else if (number instanceof Number) {return format(((Number)number).doubleValue(), toAppendTo, pos);} else {throw new IllegalArgumentException("Cannot format given Object as a Number");}}/*** Parses text from a string to produce a <code>Number</code>.* <p>* The method attempts to parse text starting at the index given by* <code>pos</code>.* If parsing succeeds, then the index of <code>pos</code> is updated* to the index after the last character used (parsing does not necessarily* use all characters up to the end of the string), and the parsed* number is returned. The updated <code>pos</code> can be used to* indicate the starting point for the next call to this method.* If an error occurs, then the index of <code>pos</code> is not* changed, the error index of <code>pos</code> is set to the index of* the character where the error occurred, and null is returned.* <p>* See the {@link #parse(String, ParsePosition)} method for more information* on number parsing.** @param source A <code>String</code>, part of which should be parsed.* @param pos A <code>ParsePosition</code> object with index and error* index information as described above.* @return A <code>Number</code> parsed from the string. In case of* error, returns null.* @throws NullPointerException if {@code source} or {@code pos} is null.*/@Overridepublic final Object parseObject(String source, ParsePosition pos) {return parse(source, pos);}/*** Specialization of format.** @param number the double number to format* @return the formatted String* @exception ArithmeticException if rounding is needed with rounding* mode being set to RoundingMode.UNNECESSARY* @see java.text.Format#format*/public final String format(double number) {// Use fast-path for double result if that worksString result = fastFormat(number);if (result != null)return result;return format(number, new StringBuffer(),DontCareFieldPosition.INSTANCE).toString();}/** fastFormat() is supposed to be implemented in concrete subclasses only.* Default implem always returns null.*/String fastFormat(double number) { return null; }/*** Specialization of format.** @param number the long number to format* @return the formatted String* @exception ArithmeticException if rounding is needed with rounding* mode being set to RoundingMode.UNNECESSARY* @see java.text.Format#format*/public final String format(long number) {return format(number, new StringBuffer(),DontCareFieldPosition.INSTANCE).toString();}/*** Specialization of format.** @param number the double number to format* @param toAppendTo the StringBuffer to which the formatted text is to be* appended* @param pos keeps track on the position of the field within the* returned string. For example, for formatting a number* {@code 1234567.89} in {@code Locale.US} locale,* if the given {@code fieldPosition} is* {@link NumberFormat#INTEGER_FIELD}, the begin index* and end index of {@code fieldPosition} will be set* to 0 and 9, respectively for the output string* {@code 1,234,567.89}.* @return the formatted StringBuffer* @exception ArithmeticException if rounding is needed with rounding* mode being set to RoundingMode.UNNECESSARY* @see java.text.Format#format*/public abstract StringBuffer format(double number,StringBuffer toAppendTo,FieldPosition pos);/*** Specialization of format.** @param number the long number to format* @param toAppendTo the StringBuffer to which the formatted text is to be* appended* @param pos keeps track on the position of the field within the* returned string. For example, for formatting a number* {@code 123456789} in {@code Locale.US} locale,* if the given {@code fieldPosition} is* {@link NumberFormat#INTEGER_FIELD}, the begin index* and end index of {@code fieldPosition} will be set* to 0 and 11, respectively for the output string* {@code 123,456,789}.* @return the formatted StringBuffer* @exception ArithmeticException if rounding is needed with rounding* mode being set to RoundingMode.UNNECESSARY* @see java.text.Format#format*/public abstract StringBuffer format(long number,StringBuffer toAppendTo,FieldPosition pos);/*** Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,* Long.MAX_VALUE] and with no decimals), otherwise a Double.* If IntegerOnly is set, will stop at a decimal* point (or equivalent; e.g., for rational numbers "1 2/3", will stop* after the 1).* Does not throw an exception; if no object can be parsed, index is* unchanged!** @param source the String to parse* @param parsePosition the parse position* @return the parsed value* @see java.text.NumberFormat#isParseIntegerOnly* @see java.text.Format#parseObject*/public abstract Number parse(String source, ParsePosition parsePosition);/*** Parses text from the beginning of the given string to produce a number.* The method may not use the entire text of the given string.* <p>* See the {@link #parse(String, ParsePosition)} method for more information* on number parsing.** @param source A <code>String</code> whose beginning should be parsed.* @return A <code>Number</code> parsed from the string.* @exception ParseException if the beginning of the specified string* cannot be parsed.*/public Number parse(String source) throws ParseException {ParsePosition parsePosition = new ParsePosition(0);Number result = parse(source, parsePosition);if (parsePosition.index == 0) {throw new ParseException("Unparseable number: \"" + source + "\"",parsePosition.errorIndex);}return result;}/*** Returns true if this format will parse numbers as integers only.* For example in the English locale, with ParseIntegerOnly true, the* string "1234." would be parsed as the integer value 1234 and parsing* would stop at the "." character. Of course, the exact format accepted* by the parse operation is locale dependent and determined by sub-classes* of NumberFormat.** @return {@code true} if numbers should be parsed as integers only;* {@code false} otherwise*/public boolean isParseIntegerOnly() {return parseIntegerOnly;}/*** Sets whether or not numbers should be parsed as integers only.** @param value {@code true} if numbers should be parsed as integers only;* {@code false} otherwise* @see #isParseIntegerOnly*/public void setParseIntegerOnly(boolean value) {parseIntegerOnly = value;}//============== Locale Stuff =====================/*** Returns a general-purpose number format for the current default* {@link java.util.Locale.Category#FORMAT FORMAT} locale.* This is the same as calling* {@link #getNumberInstance() getNumberInstance()}.** @return the {@code NumberFormat} instance for general-purpose number* formatting*/public static final NumberFormat getInstance() {return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);}/*** Returns a general-purpose number format for the specified locale.* This is the same as calling* {@link #getNumberInstance(java.util.Locale) getNumberInstance(inLocale)}.** @param inLocale the desired locale* @return the {@code NumberFormat} instance for general-purpose number* formatting*/public static NumberFormat getInstance(Locale inLocale) {return getInstance(inLocale, NUMBERSTYLE);}/*** Returns a general-purpose number format for the current default* {@link java.util.Locale.Category#FORMAT FORMAT} locale.* <p>This is equivalent to calling* {@link #getNumberInstance(Locale)* getNumberInstance(Locale.getDefault(Locale.Category.FORMAT))}.** @return the {@code NumberFormat} instance for general-purpose number* formatting* @see java.util.Locale#getDefault(java.util.Locale.Category)* @see java.util.Locale.Category#FORMAT*/public static final NumberFormat getNumberInstance() {return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);}/*** Returns a general-purpose number format for the specified locale.** @param inLocale the desired locale* @return the {@code NumberFormat} instance for general-purpose number* formatting*/public static NumberFormat getNumberInstance(Locale inLocale) {return getInstance(inLocale, NUMBERSTYLE);}/*** Returns an integer number format for the current default* {@link java.util.Locale.Category#FORMAT FORMAT} locale. The* returned number format is configured to round floating point numbers* to the nearest integer using half-even rounding (see {@link* java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,* and to parse only the integer part of an input string (see {@link* #isParseIntegerOnly isParseIntegerOnly}).* <p>This is equivalent to calling* {@link #getIntegerInstance(Locale)* getIntegerInstance(Locale.getDefault(Locale.Category.FORMAT))}.** @see #getRoundingMode()* @see java.util.Locale#getDefault(java.util.Locale.Category)* @see java.util.Locale.Category#FORMAT* @return a number format for integer values* @since 1.4*/public static final NumberFormat getIntegerInstance() {return getInstance(Locale.getDefault(Locale.Category.FORMAT), INTEGERSTYLE);}/*** Returns an integer number format for the specified locale. The* returned number format is configured to round floating point numbers* to the nearest integer using half-even rounding (see {@link* java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting,* and to parse only the integer part of an input string (see {@link* #isParseIntegerOnly isParseIntegerOnly}).** @param inLocale the desired locale* @see #getRoundingMode()* @return a number format for integer values* @since 1.4*/public static NumberFormat getIntegerInstance(Locale inLocale) {return getInstance(inLocale, INTEGERSTYLE);}/*** Returns a currency format for the current default* {@link java.util.Locale.Category#FORMAT FORMAT} locale.* <p>This is equivalent to calling* {@link #getCurrencyInstance(Locale)* getCurrencyInstance(Locale.getDefault(Locale.Category.FORMAT))}.** @return the {@code NumberFormat} instance for currency formatting* @see java.util.Locale#getDefault(java.util.Locale.Category)* @see java.util.Locale.Category#FORMAT*/public static final NumberFormat getCurrencyInstance() {return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE);}/*** Returns a currency format for the specified locale.** @param inLocale the desired locale* @return the {@code NumberFormat} instance for currency formatting*/public static NumberFormat getCurrencyInstance(Locale inLocale) {return getInstance(inLocale, CURRENCYSTYLE);}/*** Returns a percentage format for the current default* {@link java.util.Locale.Category#FORMAT FORMAT} locale.* <p>This is equivalent to calling* {@link #getPercentInstance(Locale)* getPercentInstance(Locale.getDefault(Locale.Category.FORMAT))}.** @return the {@code NumberFormat} instance for percentage formatting* @see java.util.Locale#getDefault(java.util.Locale.Category)* @see java.util.Locale.Category#FORMAT*/public static final NumberFormat getPercentInstance() {return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE);}/*** Returns a percentage format for the specified locale.** @param inLocale the desired locale* @return the {@code NumberFormat} instance for percentage formatting*/public static NumberFormat getPercentInstance(Locale inLocale) {return getInstance(inLocale, PERCENTSTYLE);}/*** Returns a scientific format for the current default locale.*//*public*/ final static NumberFormat getScientificInstance() {return getInstance(Locale.getDefault(Locale.Category.FORMAT), SCIENTIFICSTYLE);}/*** Returns a scientific format for the specified locale.** @param inLocale the desired locale*//*public*/ static NumberFormat getScientificInstance(Locale inLocale) {return getInstance(inLocale, SCIENTIFICSTYLE);}/*** Returns an array of all locales for which the* <code>get*Instance</code> methods of this class can return* localized instances.* The returned array represents the union of locales supported by the Java* runtime and by installed* {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations.* It must contain at least a <code>Locale</code> instance equal to* {@link java.util.Locale#US Locale.US}.** @return An array of locales for which localized* <code>NumberFormat</code> instances are available.*/public static Locale[] getAvailableLocales() {LocaleServiceProviderPool pool =LocaleServiceProviderPool.getPool(NumberFormatProvider.class);return pool.getAvailableLocales();}/*** Overrides hashCode.*/@Overridepublic int hashCode() {return maximumIntegerDigits * 37 + maxFractionDigits;// just enough fields for a reasonable distribution}/*** Overrides equals.*/@Overridepublic boolean equals(Object obj) {if (obj == null) {return false;}if (this == obj) {return true;}if (getClass() != obj.getClass()) {return false;}NumberFormat other = (NumberFormat) obj;return (maximumIntegerDigits == other.maximumIntegerDigits&& minimumIntegerDigits == other.minimumIntegerDigits&& maximumFractionDigits == other.maximumFractionDigits&& minimumFractionDigits == other.minimumFractionDigits&& groupingUsed == other.groupingUsed&& parseIntegerOnly == other.parseIntegerOnly);}/*** Overrides Cloneable.*/@Overridepublic Object clone() {NumberFormat other = (NumberFormat) super.clone();return other;}/*** Returns true if grouping is used in this format. For example, in the* English locale, with grouping on, the number 1234567 might be formatted* as "1,234,567". The grouping separator as well as the size of each group* is locale dependent and is determined by sub-classes of NumberFormat.** @return {@code true} if grouping is used;* {@code false} otherwise* @see #setGroupingUsed*/public boolean isGroupingUsed() {return groupingUsed;}/*** Set whether or not grouping will be used in this format.** @param newValue {@code true} if grouping is used;* {@code false} otherwise* @see #isGroupingUsed*/public void setGroupingUsed(boolean newValue) {groupingUsed = newValue;}/*** Returns the maximum number of digits allowed in the integer portion of a* number.** @return the maximum number of digits* @see #setMaximumIntegerDigits*/public int getMaximumIntegerDigits() {return maximumIntegerDigits;}/*** Sets the maximum number of digits allowed in the integer portion of a* number. maximumIntegerDigits must be ≥ minimumIntegerDigits. If the* new value for maximumIntegerDigits is less than the current value* of minimumIntegerDigits, then minimumIntegerDigits will also be set to* the new value.** @param newValue the maximum number of integer digits to be shown; if* less than zero, then zero is used. The concrete subclass may enforce an* upper limit to this value appropriate to the numeric type being formatted.* @see #getMaximumIntegerDigits*/public void setMaximumIntegerDigits(int newValue) {maximumIntegerDigits = Math.max(0,newValue);if (minimumIntegerDigits > maximumIntegerDigits) {minimumIntegerDigits = maximumIntegerDigits;}}/*** Returns the minimum number of digits allowed in the integer portion of a* number.** @return the minimum number of digits* @see #setMinimumIntegerDigits*/public int getMinimumIntegerDigits() {return minimumIntegerDigits;}/*** Sets the minimum number of digits allowed in the integer portion of a* number. minimumIntegerDigits must be ≤ maximumIntegerDigits. If the* new value for minimumIntegerDigits exceeds the current value* of maximumIntegerDigits, then maximumIntegerDigits will also be set to* the new value** @param newValue the minimum number of integer digits to be shown; if* less than zero, then zero is used. The concrete subclass may enforce an* upper limit to this value appropriate to the numeric type being formatted.* @see #getMinimumIntegerDigits*/public void setMinimumIntegerDigits(int newValue) {minimumIntegerDigits = Math.max(0,newValue);if (minimumIntegerDigits > maximumIntegerDigits) {maximumIntegerDigits = minimumIntegerDigits;}}/*** Returns the maximum number of digits allowed in the fraction portion of a* number.** @return the maximum number of digits.* @see #setMaximumFractionDigits*/public int getMaximumFractionDigits() {return maximumFractionDigits;}/*** Sets the maximum number of digits allowed in the fraction portion of a* number. maximumFractionDigits must be ≥ minimumFractionDigits. If the* new value for maximumFractionDigits is less than the current value* of minimumFractionDigits, then minimumFractionDigits will also be set to* the new value.** @param newValue the maximum number of fraction digits to be shown; if* less than zero, then zero is used. The concrete subclass may enforce an* upper limit to this value appropriate to the numeric type being formatted.* @see #getMaximumFractionDigits*/public void setMaximumFractionDigits(int newValue) {maximumFractionDigits = Math.max(0,newValue);if (maximumFractionDigits < minimumFractionDigits) {minimumFractionDigits = maximumFractionDigits;}}/*** Returns the minimum number of digits allowed in the fraction portion of a* number.** @return the minimum number of digits* @see #setMinimumFractionDigits*/public int getMinimumFractionDigits() {return minimumFractionDigits;}/*** Sets the minimum number of digits allowed in the fraction portion of a* number. minimumFractionDigits must be ≤ maximumFractionDigits. If the* new value for minimumFractionDigits exceeds the current value* of maximumFractionDigits, then maximumIntegerDigits will also be set to* the new value** @param newValue the minimum number of fraction digits to be shown; if* less than zero, then zero is used. The concrete subclass may enforce an* upper limit to this value appropriate to the numeric type being formatted.* @see #getMinimumFractionDigits*/public void setMinimumFractionDigits(int newValue) {minimumFractionDigits = Math.max(0,newValue);if (maximumFractionDigits < minimumFractionDigits) {maximumFractionDigits = minimumFractionDigits;}}/*** Gets the currency used by this number format when formatting* currency values. The initial value is derived in a locale dependent* way. The returned value may be null if no valid* currency could be determined and no currency has been set using* {@link #setCurrency(java.util.Currency) setCurrency}.* <p>* The default implementation throws* <code>UnsupportedOperationException</code>.** @return the currency used by this number format, or <code>null</code>* @exception UnsupportedOperationException if the number format class* doesn't implement currency formatting* @since 1.4*/public Currency getCurrency() {throw new UnsupportedOperationException();}/*** Sets the currency used by this number format when formatting* currency values. This does not update the minimum or maximum* number of fraction digits used by the number format.* <p>* The default implementation throws* <code>UnsupportedOperationException</code>.** @param currency the new currency to be used by this number format* @exception UnsupportedOperationException if the number format class* doesn't implement currency formatting* @exception NullPointerException if <code>currency</code> is null* @since 1.4*/public void setCurrency(Currency currency) {throw new UnsupportedOperationException();}/*** Gets the {@link java.math.RoundingMode} used in this NumberFormat.* The default implementation of this method in NumberFormat* always throws {@link java.lang.UnsupportedOperationException}.* Subclasses which handle different rounding modes should override* this method.** @exception UnsupportedOperationException The default implementation* always throws this exception* @return The <code>RoundingMode</code> used for this NumberFormat.* @see #setRoundingMode(RoundingMode)* @since 1.6*/public RoundingMode getRoundingMode() {throw new UnsupportedOperationException();}/*** Sets the {@link java.math.RoundingMode} used in this NumberFormat.* The default implementation of this method in NumberFormat always* throws {@link java.lang.UnsupportedOperationException}.* Subclasses which handle different rounding modes should override* this method.** @exception UnsupportedOperationException The default implementation* always throws this exception* @exception NullPointerException if <code>roundingMode</code> is null* @param roundingMode The <code>RoundingMode</code> to be used* @see #getRoundingMode()* @since 1.6*/public void setRoundingMode(RoundingMode roundingMode) {throw new UnsupportedOperationException();}// =======================privates===============================private static NumberFormat getInstance(Locale desiredLocale,int choice) {LocaleProviderAdapter adapter;adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class,desiredLocale);NumberFormat numberFormat = getInstance(adapter, desiredLocale, choice);if (numberFormat == null) {numberFormat = getInstance(LocaleProviderAdapter.forJRE(),desiredLocale, choice);}return numberFormat;}private static NumberFormat getInstance(LocaleProviderAdapter adapter,Locale locale, int choice) {NumberFormatProvider provider = adapter.getNumberFormatProvider();NumberFormat numberFormat = null;switch (choice) {case NUMBERSTYLE:numberFormat = provider.getNumberInstance(locale);break;case PERCENTSTYLE:numberFormat = provider.getPercentInstance(locale);break;case CURRENCYSTYLE:numberFormat = provider.getCurrencyInstance(locale);break;case INTEGERSTYLE:numberFormat = provider.getIntegerInstance(locale);break;}return numberFormat;}/*** First, read in the default serializable data.** Then, if <code>serialVersionOnStream</code> is less than 1, indicating that* the stream was written by JDK 1.1,* set the <code>int</code> fields such as <code>maximumIntegerDigits</code>* to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,* since the <code>int</code> fields were not present in JDK 1.1.* Finally, set serialVersionOnStream back to the maximum allowed value so that* default serialization will work properly if this object is streamed out again.** <p>If <code>minimumIntegerDigits</code> is greater than* <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code>* is greater than <code>maximumFractionDigits</code>, then the stream data* is invalid and this method throws an <code>InvalidObjectException</code>.* In addition, if any of these values is negative, then this method throws* an <code>InvalidObjectException</code>.** @since 1.2*/private void readObject(ObjectInputStream stream)throws IOException, ClassNotFoundException{stream.defaultReadObject();if (serialVersionOnStream < 1) {// Didn't have additional int fields, reassign to use them.maximumIntegerDigits = maxIntegerDigits;minimumIntegerDigits = minIntegerDigits;maximumFractionDigits = maxFractionDigits;minimumFractionDigits = minFractionDigits;}if (minimumIntegerDigits > maximumIntegerDigits ||minimumFractionDigits > maximumFractionDigits ||minimumIntegerDigits < 0 || minimumFractionDigits < 0) {throw new InvalidObjectException("Digit count range invalid");}serialVersionOnStream = currentSerialVersion;}/*** Write out the default serializable data, after first setting* the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be* equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>* (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility* with the JDK 1.1 version of the stream format.** @since 1.2*/private void writeObject(ObjectOutputStream stream)throws IOException{maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ?Byte.MAX_VALUE : (byte)maximumIntegerDigits;minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ?Byte.MAX_VALUE : (byte)minimumIntegerDigits;maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ?Byte.MAX_VALUE : (byte)maximumFractionDigits;minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ?Byte.MAX_VALUE : (byte)minimumFractionDigits;stream.defaultWriteObject();}// Constants used by factory methods to specify a style of format.private static final int NUMBERSTYLE = 0;private static final int CURRENCYSTYLE = 1;private static final int PERCENTSTYLE = 2;private static final int SCIENTIFICSTYLE = 3;private static final int INTEGERSTYLE = 4;/*** True if the grouping (i.e. thousands) separator is used when* formatting and parsing numbers.** @serial* @see #isGroupingUsed*/private boolean groupingUsed = true;/*** The maximum number of digits allowed in the integer portion of a* number. <code>maxIntegerDigits</code> must be greater than or equal to* <code>minIntegerDigits</code>.* <p>* <strong>Note:</strong> This field exists only for serialization* compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new* <code>int</code> field <code>maximumIntegerDigits</code> is used instead.* When writing to a stream, <code>maxIntegerDigits</code> is set to* <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,* whichever is smaller. When reading from a stream, this field is used* only if <code>serialVersionOnStream</code> is less than 1.** @serial* @see #getMaximumIntegerDigits*/private byte maxIntegerDigits = 40;/*** The minimum number of digits allowed in the integer portion of a* number. <code>minimumIntegerDigits</code> must be less than or equal to* <code>maximumIntegerDigits</code>.* <p>* <strong>Note:</strong> This field exists only for serialization* compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new* <code>int</code> field <code>minimumIntegerDigits</code> is used instead.* When writing to a stream, <code>minIntegerDigits</code> is set to* <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,* whichever is smaller. When reading from a stream, this field is used* only if <code>serialVersionOnStream</code> is less than 1.** @serial* @see #getMinimumIntegerDigits*/private byte minIntegerDigits = 1;/*** The maximum number of digits allowed in the fractional portion of a* number. <code>maximumFractionDigits</code> must be greater than or equal to* <code>minimumFractionDigits</code>.* <p>* <strong>Note:</strong> This field exists only for serialization* compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new* <code>int</code> field <code>maximumFractionDigits</code> is used instead.* When writing to a stream, <code>maxFractionDigits</code> is set to* <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,* whichever is smaller. When reading from a stream, this field is used* only if <code>serialVersionOnStream</code> is less than 1.** @serial* @see #getMaximumFractionDigits*/private byte maxFractionDigits = 3; // invariant, >= minFractionDigits/*** The minimum number of digits allowed in the fractional portion of a* number. <code>minimumFractionDigits</code> must be less than or equal to* <code>maximumFractionDigits</code>.* <p>* <strong>Note:</strong> This field exists only for serialization* compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new* <code>int</code> field <code>minimumFractionDigits</code> is used instead.* When writing to a stream, <code>minFractionDigits</code> is set to* <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,* whichever is smaller. When reading from a stream, this field is used* only if <code>serialVersionOnStream</code> is less than 1.** @serial* @see #getMinimumFractionDigits*/private byte minFractionDigits = 0;/*** True if this format will parse numbers as integers only.** @serial* @see #isParseIntegerOnly*/private boolean parseIntegerOnly = false;// new fields for 1.2. byte is too small for integer digits./*** The maximum number of digits allowed in the integer portion of a* number. <code>maximumIntegerDigits</code> must be greater than or equal to* <code>minimumIntegerDigits</code>.** @serial* @since 1.2* @see #getMaximumIntegerDigits*/private int maximumIntegerDigits = 40;/*** The minimum number of digits allowed in the integer portion of a* number. <code>minimumIntegerDigits</code> must be less than or equal to* <code>maximumIntegerDigits</code>.** @serial* @since 1.2* @see #getMinimumIntegerDigits*/private int minimumIntegerDigits = 1;/*** The maximum number of digits allowed in the fractional portion of a* number. <code>maximumFractionDigits</code> must be greater than or equal to* <code>minimumFractionDigits</code>.** @serial* @since 1.2* @see #getMaximumFractionDigits*/private int maximumFractionDigits = 3; // invariant, >= minFractionDigits/*** The minimum number of digits allowed in the fractional portion of a* number. <code>minimumFractionDigits</code> must be less than or equal to* <code>maximumFractionDigits</code>.** @serial* @since 1.2* @see #getMinimumFractionDigits*/private int minimumFractionDigits = 0;static final int currentSerialVersion = 1;/*** Describes the version of <code>NumberFormat</code> present on the stream.* Possible values are:* <ul>* <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.* In this version, the <code>int</code> fields such as* <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>* fields such as <code>maxIntegerDigits</code> are used instead.** <li><b>1</b>: the 1.2 version of the stream format. The values of the* <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,* and the <code>int</code> fields such as <code>maximumIntegerDigits</code>* are used instead.* </ul>* When streaming out a <code>NumberFormat</code>, the most recent format* (corresponding to the highest allowable <code>serialVersionOnStream</code>)* is always written.** @serial* @since 1.2*/private int serialVersionOnStream = currentSerialVersion;// Removed "implements Cloneable" clause. Needs to update serialization// ID for backward compatibility.static final long serialVersionUID = -2308460125733713944L;//// class for AttributedCharacterIterator attributes///*** Defines constants that are used as attribute keys in the* <code>AttributedCharacterIterator</code> returned* from <code>NumberFormat.formatToCharacterIterator</code> and as* field identifiers in <code>FieldPosition</code>.** @since 1.4*/public static class Field extends Format.Field {// Proclaim serial compatibility with 1.4 FCSprivate static final long serialVersionUID = 7494728892700160890L;// table of all instances in this class, used by readResolveprivate static final Map<String, Field> instanceMap = new HashMap<>(11);/*** Creates a Field instance with the specified* name.** @param name Name of the attribute*/protected Field(String name) {super(name);if (this.getClass() == NumberFormat.Field.class) {instanceMap.put(name, this);}}/*** Resolves instances being deserialized to the predefined constants.** @throws InvalidObjectException if the constant could not be resolved.* @return resolved NumberFormat.Field constant*/@Overrideprotected Object readResolve() throws InvalidObjectException {if (this.getClass() != NumberFormat.Field.class) {throw new InvalidObjectException("subclass didn't correctly implement readResolve");}Object instance = instanceMap.get(getName());if (instance != null) {return instance;} else {throw new InvalidObjectException("unknown attribute name");}}/*** Constant identifying the integer field.*/public static final Field INTEGER = new Field("integer");/*** Constant identifying the fraction field.*/public static final Field FRACTION = new Field("fraction");/*** Constant identifying the exponent field.*/public static final Field EXPONENT = new Field("exponent");/*** Constant identifying the decimal separator field.*/public static final Field DECIMAL_SEPARATOR =new Field("decimal separator");/*** Constant identifying the sign field.*/public static final Field SIGN = new Field("sign");/*** Constant identifying the grouping separator field.*/public static final Field GROUPING_SEPARATOR =new Field("grouping separator");/*** Constant identifying the exponent symbol field.*/public static final Field EXPONENT_SYMBOL = newField("exponent symbol");/*** Constant identifying the percent field.*/public static final Field PERCENT = new Field("percent");/*** Constant identifying the permille field.*/public static final Field PERMILLE = new Field("per mille");/*** Constant identifying the currency field.*/public static final Field CURRENCY = new Field("currency");/*** Constant identifying the exponent sign field.*/public static final Field EXPONENT_SIGN = new Field("exponent sign");}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。