src/share/classes/java/text/NumberFormat.java

Print this page
rev 5696 : 6336885: RFE: Locale Data Deployment Enhancements
4609153: Provide locale data for Indic locales
5104387: Support for gl_ES locale (galician language)
6337471: desktop/system locale preferences support
7056139: (cal) SPI support for locale-dependent Calendar parameters
7058206: Provide CalendarData SPI for week params and display field value names
7073852: Support multiple scripts for digits and decimal symbols per locale
7079560: [Fmt-Da] Context dependent month names support in SimpleDateFormat
7171324: getAvailableLocales() of locale sensitive services should return the actual availability of locales
7151414: (cal) Support calendar type identification
7168528: LocaleServiceProvider needs to be aware of Locale extensions
7171372: (cal) locale's default Calendar should be created if unknown calendar is specified
Summary: JEP 127: Improve Locale Data Packaging and Adopt Unicode CLDR Data (part 1 w/o packaging changes. by Naoto Sato and Masayoshi Okutsu)


  37  */
  38 
  39 package java.text;
  40 
  41 import java.io.InvalidObjectException;
  42 import java.io.IOException;
  43 import java.io.ObjectInputStream;
  44 import java.io.ObjectOutputStream;
  45 import java.math.BigInteger;
  46 import java.math.RoundingMode;
  47 import java.text.spi.NumberFormatProvider;
  48 import java.util.Currency;
  49 import java.util.HashMap;
  50 import java.util.Hashtable;
  51 import java.util.Locale;
  52 import java.util.Map;
  53 import java.util.ResourceBundle;
  54 import java.util.concurrent.atomic.AtomicInteger;
  55 import java.util.concurrent.atomic.AtomicLong;
  56 import java.util.spi.LocaleServiceProvider;
  57 import sun.util.LocaleServiceProviderPool;

  58 import sun.util.resources.LocaleData;
  59 
  60 /**
  61  * <code>NumberFormat</code> is the abstract base class for all number
  62  * formats. This class provides the interface for formatting and parsing
  63  * numbers. <code>NumberFormat</code> also provides methods for determining
  64  * which locales have number formats, and what their names are.
  65  *
  66  * <p>
  67  * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
  68  * Your code can be completely independent of the locale conventions for
  69  * decimal points, thousands-separators, or even the particular decimal
  70  * digits used, or whether the number format is even decimal.
  71  *
  72  * <p>
  73  * To format a number for the current Locale, use one of the factory
  74  * class methods:
  75  * <blockquote>
  76  * <pre>
  77  *  myString = NumberFormat.getInstance().format(myNumber);


 215      * and {@link java.lang.Number#doubleValue()} for all other types. It
 216      * then calls
 217      * {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)}
 218      * or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}.
 219      * This may result in loss of magnitude information and precision for
 220      * <code>BigInteger</code> and <code>BigDecimal</code> values.
 221      * @param number     the number to format
 222      * @param toAppendTo the <code>StringBuffer</code> to which the formatted
 223      *                   text is to be appended
 224      * @param pos        On input: an alignment field, if desired.
 225      *                   On output: the offsets of the alignment field.
 226      * @return           the value passed in as <code>toAppendTo</code>
 227      * @exception        IllegalArgumentException if <code>number</code> is
 228      *                   null or not an instance of <code>Number</code>.
 229      * @exception        NullPointerException if <code>toAppendTo</code> or
 230      *                   <code>pos</code> is null
 231      * @exception        ArithmeticException if rounding is needed with rounding
 232      *                   mode being set to RoundingMode.UNNECESSARY
 233      * @see              java.text.FieldPosition
 234      */

 235     public StringBuffer format(Object number,
 236                                StringBuffer toAppendTo,
 237                                FieldPosition pos) {
 238         if (number instanceof Long || number instanceof Integer ||
 239             number instanceof Short || number instanceof Byte ||
 240             number instanceof AtomicInteger || number instanceof AtomicLong ||
 241             (number instanceof BigInteger &&
 242              ((BigInteger)number).bitLength() < 64)) {
 243             return format(((Number)number).longValue(), toAppendTo, pos);
 244         } else if (number instanceof Number) {
 245             return format(((Number)number).doubleValue(), toAppendTo, pos);
 246         } else {
 247             throw new IllegalArgumentException("Cannot format given Object as a Number");
 248         }
 249     }
 250 
 251     /**
 252      * Parses text from a string to produce a <code>Number</code>.
 253      * <p>
 254      * The method attempts to parse text starting at the index given by
 255      * <code>pos</code>.
 256      * If parsing succeeds, then the index of <code>pos</code> is updated
 257      * to the index after the last character used (parsing does not necessarily
 258      * use all characters up to the end of the string), and the parsed
 259      * number is returned. The updated <code>pos</code> can be used to
 260      * indicate the starting point for the next call to this method.
 261      * If an error occurs, then the index of <code>pos</code> is not
 262      * changed, the error index of <code>pos</code> is set to the index of
 263      * the character where the error occurred, and null is returned.
 264      * <p>
 265      * See the {@link #parse(String, ParsePosition)} method for more information
 266      * on number parsing.
 267      *
 268      * @param source A <code>String</code>, part of which should be parsed.
 269      * @param pos A <code>ParsePosition</code> object with index and error
 270      *            index information as described above.
 271      * @return A <code>Number</code> parsed from the string. In case of
 272      *         error, returns null.
 273      * @exception NullPointerException if <code>pos</code> is null.
 274      */

 275     public final Object parseObject(String source, ParsePosition pos) {
 276         return parse(source, pos);
 277     }
 278 
 279    /**
 280      * Specialization of format.
 281      * @exception        ArithmeticException if rounding is needed with rounding
 282      *                   mode being set to RoundingMode.UNNECESSARY
 283      * @see java.text.Format#format
 284      */
 285     public final String format(double number) {
 286         return format(number, new StringBuffer(),
 287                       DontCareFieldPosition.INSTANCE).toString();
 288     }
 289 
 290    /**
 291      * Specialization of format.
 292      * @exception        ArithmeticException if rounding is needed with rounding
 293      *                   mode being set to RoundingMode.UNNECESSARY
 294      * @see java.text.Format#format


 484     /**
 485      * Returns an array of all locales for which the
 486      * <code>get*Instance</code> methods of this class can return
 487      * localized instances.
 488      * The returned array represents the union of locales supported by the Java
 489      * runtime and by installed
 490      * {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations.
 491      * It must contain at least a <code>Locale</code> instance equal to
 492      * {@link java.util.Locale#US Locale.US}.
 493      *
 494      * @return An array of locales for which localized
 495      *         <code>NumberFormat</code> instances are available.
 496      */
 497     public static Locale[] getAvailableLocales() {
 498         LocaleServiceProviderPool pool =
 499             LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
 500         return pool.getAvailableLocales();
 501     }
 502 
 503     /**
 504      * Overrides hashCode
 505      */

 506     public int hashCode() {
 507         return maximumIntegerDigits * 37 + maxFractionDigits;
 508         // just enough fields for a reasonable distribution
 509     }
 510 
 511     /**
 512      * Overrides equals
 513      */

 514     public boolean equals(Object obj) {
 515         if (obj == null) {
 516             return false;
 517         }
 518         if (this == obj) {
 519             return true;
 520         }
 521         if (getClass() != obj.getClass()) {
 522             return false;
 523         }
 524         NumberFormat other = (NumberFormat) obj;
 525         return (maximumIntegerDigits == other.maximumIntegerDigits
 526             && minimumIntegerDigits == other.minimumIntegerDigits
 527             && maximumFractionDigits == other.maximumFractionDigits
 528             && minimumFractionDigits == other.minimumFractionDigits
 529             && groupingUsed == other.groupingUsed
 530             && parseIntegerOnly == other.parseIntegerOnly);
 531     }
 532 
 533     /**
 534      * Overrides Cloneable
 535      */

 536     public Object clone() {
 537         NumberFormat other = (NumberFormat) super.clone();
 538         return other;
 539     }
 540 
 541     /**
 542      * Returns true if grouping is used in this format. For example, in the
 543      * English locale, with grouping on, the number 1234567 might be formatted
 544      * as "1,234,567". The grouping separator as well as the size of each group
 545      * is locale dependant and is determined by sub-classes of NumberFormat.
 546      * @see #setGroupingUsed
 547      */
 548     public boolean isGroupingUsed() {
 549         return groupingUsed;
 550     }
 551 
 552     /**
 553      * Set whether or not grouping will be used in this format.
 554      * @see #isGroupingUsed
 555      */


 724      * The default implementation of this method in NumberFormat always
 725      * throws {@link java.lang.UnsupportedOperationException}.
 726      * Subclasses which handle different rounding modes should override
 727      * this method.
 728      *
 729      * @exception UnsupportedOperationException The default implementation
 730      *     always throws this exception
 731      * @exception NullPointerException if <code>roundingMode</code> is null
 732      * @param roundingMode The <code>RoundingMode</code> to be used
 733      * @see #getRoundingMode()
 734      * @since 1.6
 735      */
 736     public void setRoundingMode(RoundingMode roundingMode) {
 737         throw new UnsupportedOperationException();
 738     }
 739 
 740     // =======================privates===============================
 741 
 742     private static NumberFormat getInstance(Locale desiredLocale,
 743                                            int choice) {
 744         // Check whether a provider can provide an implementation that's closer
 745         // to the requested locale than what the Java runtime itself can provide.
 746         LocaleServiceProviderPool pool =
 747             LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
 748         if (pool.hasProviders()) {
 749             NumberFormat providersInstance = pool.getLocalizedObject(
 750                                     NumberFormatGetter.INSTANCE,
 751                                     desiredLocale,
 752                                     choice);
 753             if (providersInstance != null) {
 754                 return providersInstance;
 755             }

 756         }
 757 
 758         /* try the cache first */
 759         String[] numberPatterns = cachedLocaleData.get(desiredLocale);
 760         if (numberPatterns == null) { /* cache miss */
 761             ResourceBundle resource = LocaleData.getNumberFormatData(desiredLocale);
 762             numberPatterns = resource.getStringArray("NumberPatterns");
 763             /* update cache */
 764             cachedLocaleData.put(desiredLocale, numberPatterns);










 765         }
 766 
 767         DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(desiredLocale);
 768         int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : choice;
 769         DecimalFormat format = new DecimalFormat(numberPatterns[entry], symbols);
 770 
 771         if (choice == INTEGERSTYLE) {
 772             format.setMaximumFractionDigits(0);
 773             format.setDecimalSeparatorAlwaysShown(false);
 774             format.setParseIntegerOnly(true);
 775         } else if (choice == CURRENCYSTYLE) {
 776             format.adjustForCurrencyDefaultFractionDigits();
 777         }
 778 
 779         return format;
 780     }
 781 
 782     /**
 783      * First, read in the default serializable data.
 784      *
 785      * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
 786      * the stream was written by JDK 1.1,
 787      * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
 788      * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
 789      * since the <code>int</code> fields were not present in JDK 1.1.
 790      * Finally, set serialVersionOnStream back to the maximum allowed value so that
 791      * default serialization will work properly if this object is streamed out again.
 792      *
 793      * <p>If <code>minimumIntegerDigits</code> is greater than
 794      * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code>
 795      * is greater than <code>maximumFractionDigits</code>, then the stream data
 796      * is invalid and this method throws an <code>InvalidObjectException</code>.
 797      * In addition, if any of these values is negative, then this method throws
 798      * an <code>InvalidObjectException</code>.
 799      *
 800      * @since 1.2
 801      */


 824      * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
 825      * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
 826      * with the JDK 1.1 version of the stream format.
 827      *
 828      * @since 1.2
 829      */
 830     private void writeObject(ObjectOutputStream stream)
 831          throws IOException
 832     {
 833         maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ?
 834                            Byte.MAX_VALUE : (byte)maximumIntegerDigits;
 835         minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ?
 836                            Byte.MAX_VALUE : (byte)minimumIntegerDigits;
 837         maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ?
 838                             Byte.MAX_VALUE : (byte)maximumFractionDigits;
 839         minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ?
 840                             Byte.MAX_VALUE : (byte)minimumFractionDigits;
 841         stream.defaultWriteObject();
 842     }
 843 
 844     /**
 845      * Cache to hold the NumberPatterns of a Locale.
 846      */
 847     private static final Hashtable<Locale, String[]> cachedLocaleData = new Hashtable<>(3);
 848 
 849     // Constants used by factory methods to specify a style of format.
 850     private static final int NUMBERSTYLE = 0;
 851     private static final int CURRENCYSTYLE = 1;
 852     private static final int PERCENTSTYLE = 2;
 853     private static final int SCIENTIFICSTYLE = 3;
 854     private static final int INTEGERSTYLE = 4;
 855 
 856     /**
 857      * True if the grouping (i.e. thousands) separator is used when
 858      * formatting and parsing numbers.
 859      *
 860      * @serial
 861      * @see #isGroupingUsed
 862      */
 863     private boolean groupingUsed = true;
 864 
 865     /**
 866      * The maximum number of digits allowed in the integer portion of a
 867      * number.  <code>maxIntegerDigits</code> must be greater than or equal to
 868      * <code>minIntegerDigits</code>.


1039 
1040         /**
1041          * Creates a Field instance with the specified
1042          * name.
1043          *
1044          * @param name Name of the attribute
1045          */
1046         protected Field(String name) {
1047             super(name);
1048             if (this.getClass() == NumberFormat.Field.class) {
1049                 instanceMap.put(name, this);
1050             }
1051         }
1052 
1053         /**
1054          * Resolves instances being deserialized to the predefined constants.
1055          *
1056          * @throws InvalidObjectException if the constant could not be resolved.
1057          * @return resolved NumberFormat.Field constant
1058          */

1059         protected Object readResolve() throws InvalidObjectException {
1060             if (this.getClass() != NumberFormat.Field.class) {
1061                 throw new InvalidObjectException("subclass didn't correctly implement readResolve");
1062             }
1063 
1064             Object instance = instanceMap.get(getName());
1065             if (instance != null) {
1066                 return instance;
1067             } else {
1068                 throw new InvalidObjectException("unknown attribute name");
1069             }
1070         }
1071 
1072         /**
1073          * Constant identifying the integer field.
1074          */
1075         public static final Field INTEGER = new Field("integer");
1076 
1077         /**
1078          * Constant identifying the fraction field.


1110         /**
1111          * Constant identifying the percent field.
1112          */
1113         public static final Field PERCENT = new Field("percent");
1114 
1115         /**
1116          * Constant identifying the permille field.
1117          */
1118         public static final Field PERMILLE = new Field("per mille");
1119 
1120         /**
1121          * Constant identifying the currency field.
1122          */
1123         public static final Field CURRENCY = new Field("currency");
1124 
1125         /**
1126          * Constant identifying the exponent sign field.
1127          */
1128         public static final Field EXPONENT_SIGN = new Field("exponent sign");
1129     }
1130 
1131     /**
1132      * Obtains a NumberFormat instance from a NumberFormatProvider implementation.
1133      */
1134     private static class NumberFormatGetter
1135         implements LocaleServiceProviderPool.LocalizedObjectGetter<NumberFormatProvider,
1136                                                                    NumberFormat> {
1137         private static final NumberFormatGetter INSTANCE = new NumberFormatGetter();
1138 
1139         public NumberFormat getObject(NumberFormatProvider numberFormatProvider,
1140                                 Locale locale,
1141                                 String key,
1142                                 Object... params) {
1143             assert params.length == 1;
1144             int choice = (Integer)params[0];
1145 
1146             switch (choice) {
1147             case NUMBERSTYLE:
1148                 return numberFormatProvider.getNumberInstance(locale);
1149             case PERCENTSTYLE:
1150                 return numberFormatProvider.getPercentInstance(locale);
1151             case CURRENCYSTYLE:
1152                 return numberFormatProvider.getCurrencyInstance(locale);
1153             case INTEGERSTYLE:
1154                 return numberFormatProvider.getIntegerInstance(locale);
1155             default:
1156                 assert false : choice;
1157             }
1158 
1159             return null;
1160         }
1161     }
1162 }


  37  */
  38 
  39 package java.text;
  40 
  41 import java.io.InvalidObjectException;
  42 import java.io.IOException;
  43 import java.io.ObjectInputStream;
  44 import java.io.ObjectOutputStream;
  45 import java.math.BigInteger;
  46 import java.math.RoundingMode;
  47 import java.text.spi.NumberFormatProvider;
  48 import java.util.Currency;
  49 import java.util.HashMap;
  50 import java.util.Hashtable;
  51 import java.util.Locale;
  52 import java.util.Map;
  53 import java.util.ResourceBundle;
  54 import java.util.concurrent.atomic.AtomicInteger;
  55 import java.util.concurrent.atomic.AtomicLong;
  56 import java.util.spi.LocaleServiceProvider;
  57 import sun.util.locale.provider.LocaleProviderAdapter;
  58 import sun.util.locale.provider.LocaleServiceProviderPool;
  59 import sun.util.resources.LocaleData;
  60 
  61 /**
  62  * <code>NumberFormat</code> is the abstract base class for all number
  63  * formats. This class provides the interface for formatting and parsing
  64  * numbers. <code>NumberFormat</code> also provides methods for determining
  65  * which locales have number formats, and what their names are.
  66  *
  67  * <p>
  68  * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
  69  * Your code can be completely independent of the locale conventions for
  70  * decimal points, thousands-separators, or even the particular decimal
  71  * digits used, or whether the number format is even decimal.
  72  *
  73  * <p>
  74  * To format a number for the current Locale, use one of the factory
  75  * class methods:
  76  * <blockquote>
  77  * <pre>
  78  *  myString = NumberFormat.getInstance().format(myNumber);


 216      * and {@link java.lang.Number#doubleValue()} for all other types. It
 217      * then calls
 218      * {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)}
 219      * or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}.
 220      * This may result in loss of magnitude information and precision for
 221      * <code>BigInteger</code> and <code>BigDecimal</code> values.
 222      * @param number     the number to format
 223      * @param toAppendTo the <code>StringBuffer</code> to which the formatted
 224      *                   text is to be appended
 225      * @param pos        On input: an alignment field, if desired.
 226      *                   On output: the offsets of the alignment field.
 227      * @return           the value passed in as <code>toAppendTo</code>
 228      * @exception        IllegalArgumentException if <code>number</code> is
 229      *                   null or not an instance of <code>Number</code>.
 230      * @exception        NullPointerException if <code>toAppendTo</code> or
 231      *                   <code>pos</code> is null
 232      * @exception        ArithmeticException if rounding is needed with rounding
 233      *                   mode being set to RoundingMode.UNNECESSARY
 234      * @see              java.text.FieldPosition
 235      */
 236     @Override
 237     public StringBuffer format(Object number,
 238                                StringBuffer toAppendTo,
 239                                FieldPosition pos) {
 240         if (number instanceof Long || number instanceof Integer ||
 241             number instanceof Short || number instanceof Byte ||
 242             number instanceof AtomicInteger || number instanceof AtomicLong ||
 243             (number instanceof BigInteger &&
 244              ((BigInteger)number).bitLength() < 64)) {
 245             return format(((Number)number).longValue(), toAppendTo, pos);
 246         } else if (number instanceof Number) {
 247             return format(((Number)number).doubleValue(), toAppendTo, pos);
 248         } else {
 249             throw new IllegalArgumentException("Cannot format given Object as a Number");
 250         }
 251     }
 252 
 253     /**
 254      * Parses text from a string to produce a <code>Number</code>.
 255      * <p>
 256      * The method attempts to parse text starting at the index given by
 257      * <code>pos</code>.
 258      * If parsing succeeds, then the index of <code>pos</code> is updated
 259      * to the index after the last character used (parsing does not necessarily
 260      * use all characters up to the end of the string), and the parsed
 261      * number is returned. The updated <code>pos</code> can be used to
 262      * indicate the starting point for the next call to this method.
 263      * If an error occurs, then the index of <code>pos</code> is not
 264      * changed, the error index of <code>pos</code> is set to the index of
 265      * the character where the error occurred, and null is returned.
 266      * <p>
 267      * See the {@link #parse(String, ParsePosition)} method for more information
 268      * on number parsing.
 269      *
 270      * @param source A <code>String</code>, part of which should be parsed.
 271      * @param pos A <code>ParsePosition</code> object with index and error
 272      *            index information as described above.
 273      * @return A <code>Number</code> parsed from the string. In case of
 274      *         error, returns null.
 275      * @exception NullPointerException if <code>pos</code> is null.
 276      */
 277     @Override
 278     public final Object parseObject(String source, ParsePosition pos) {
 279         return parse(source, pos);
 280     }
 281 
 282    /**
 283      * Specialization of format.
 284      * @exception        ArithmeticException if rounding is needed with rounding
 285      *                   mode being set to RoundingMode.UNNECESSARY
 286      * @see java.text.Format#format
 287      */
 288     public final String format(double number) {
 289         return format(number, new StringBuffer(),
 290                       DontCareFieldPosition.INSTANCE).toString();
 291     }
 292 
 293    /**
 294      * Specialization of format.
 295      * @exception        ArithmeticException if rounding is needed with rounding
 296      *                   mode being set to RoundingMode.UNNECESSARY
 297      * @see java.text.Format#format


 487     /**
 488      * Returns an array of all locales for which the
 489      * <code>get*Instance</code> methods of this class can return
 490      * localized instances.
 491      * The returned array represents the union of locales supported by the Java
 492      * runtime and by installed
 493      * {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations.
 494      * It must contain at least a <code>Locale</code> instance equal to
 495      * {@link java.util.Locale#US Locale.US}.
 496      *
 497      * @return An array of locales for which localized
 498      *         <code>NumberFormat</code> instances are available.
 499      */
 500     public static Locale[] getAvailableLocales() {
 501         LocaleServiceProviderPool pool =
 502             LocaleServiceProviderPool.getPool(NumberFormatProvider.class);
 503         return pool.getAvailableLocales();
 504     }
 505 
 506     /**
 507      * Overrides hashCode.
 508      */
 509     @Override
 510     public int hashCode() {
 511         return maximumIntegerDigits * 37 + maxFractionDigits;
 512         // just enough fields for a reasonable distribution
 513     }
 514 
 515     /**
 516      * Overrides equals.
 517      */
 518     @Override
 519     public boolean equals(Object obj) {
 520         if (obj == null) {
 521             return false;
 522         }
 523         if (this == obj) {
 524             return true;
 525         }
 526         if (getClass() != obj.getClass()) {
 527             return false;
 528         }
 529         NumberFormat other = (NumberFormat) obj;
 530         return (maximumIntegerDigits == other.maximumIntegerDigits
 531             && minimumIntegerDigits == other.minimumIntegerDigits
 532             && maximumFractionDigits == other.maximumFractionDigits
 533             && minimumFractionDigits == other.minimumFractionDigits
 534             && groupingUsed == other.groupingUsed
 535             && parseIntegerOnly == other.parseIntegerOnly);
 536     }
 537 
 538     /**
 539      * Overrides Cloneable.
 540      */
 541     @Override
 542     public Object clone() {
 543         NumberFormat other = (NumberFormat) super.clone();
 544         return other;
 545     }
 546 
 547     /**
 548      * Returns true if grouping is used in this format. For example, in the
 549      * English locale, with grouping on, the number 1234567 might be formatted
 550      * as "1,234,567". The grouping separator as well as the size of each group
 551      * is locale dependant and is determined by sub-classes of NumberFormat.
 552      * @see #setGroupingUsed
 553      */
 554     public boolean isGroupingUsed() {
 555         return groupingUsed;
 556     }
 557 
 558     /**
 559      * Set whether or not grouping will be used in this format.
 560      * @see #isGroupingUsed
 561      */


 730      * The default implementation of this method in NumberFormat always
 731      * throws {@link java.lang.UnsupportedOperationException}.
 732      * Subclasses which handle different rounding modes should override
 733      * this method.
 734      *
 735      * @exception UnsupportedOperationException The default implementation
 736      *     always throws this exception
 737      * @exception NullPointerException if <code>roundingMode</code> is null
 738      * @param roundingMode The <code>RoundingMode</code> to be used
 739      * @see #getRoundingMode()
 740      * @since 1.6
 741      */
 742     public void setRoundingMode(RoundingMode roundingMode) {
 743         throw new UnsupportedOperationException();
 744     }
 745 
 746     // =======================privates===============================
 747 
 748     private static NumberFormat getInstance(Locale desiredLocale,
 749                                            int choice) {
 750         LocaleProviderAdapter adapter;
 751         adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class,
 752                                                    desiredLocale);
 753         NumberFormat numberFormat = getInstance(adapter, desiredLocale, choice);
 754         if (numberFormat == null) {
 755             numberFormat = getInstance(LocaleProviderAdapter.forJRE(),
 756                                        desiredLocale, choice);




 757         }
 758         return numberFormat;
 759     }
 760 
 761     private static NumberFormat getInstance(LocaleProviderAdapter adapter,
 762                                             Locale locale, int choice) {
 763         NumberFormatProvider provider = adapter.getNumberFormatProvider();
 764         NumberFormat numberFormat = null;
 765         switch (choice) {
 766         case NUMBERSTYLE:
 767             numberFormat = provider.getNumberInstance(locale);
 768             break;
 769         case PERCENTSTYLE:
 770             numberFormat = provider.getPercentInstance(locale);
 771             break;
 772         case CURRENCYSTYLE:
 773             numberFormat = provider.getCurrencyInstance(locale);
 774             break;
 775         case INTEGERSTYLE:
 776             numberFormat = provider.getIntegerInstance(locale);
 777             break;
 778         }
 779         return numberFormat;










 780     }
 781 



 782     /**
 783      * First, read in the default serializable data.
 784      *
 785      * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
 786      * the stream was written by JDK 1.1,
 787      * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
 788      * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
 789      * since the <code>int</code> fields were not present in JDK 1.1.
 790      * Finally, set serialVersionOnStream back to the maximum allowed value so that
 791      * default serialization will work properly if this object is streamed out again.
 792      *
 793      * <p>If <code>minimumIntegerDigits</code> is greater than
 794      * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code>
 795      * is greater than <code>maximumFractionDigits</code>, then the stream data
 796      * is invalid and this method throws an <code>InvalidObjectException</code>.
 797      * In addition, if any of these values is negative, then this method throws
 798      * an <code>InvalidObjectException</code>.
 799      *
 800      * @since 1.2
 801      */


 824      * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
 825      * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
 826      * with the JDK 1.1 version of the stream format.
 827      *
 828      * @since 1.2
 829      */
 830     private void writeObject(ObjectOutputStream stream)
 831          throws IOException
 832     {
 833         maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ?
 834                            Byte.MAX_VALUE : (byte)maximumIntegerDigits;
 835         minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ?
 836                            Byte.MAX_VALUE : (byte)minimumIntegerDigits;
 837         maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ?
 838                             Byte.MAX_VALUE : (byte)maximumFractionDigits;
 839         minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ?
 840                             Byte.MAX_VALUE : (byte)minimumFractionDigits;
 841         stream.defaultWriteObject();
 842     }
 843 





 844     // Constants used by factory methods to specify a style of format.
 845     private static final int NUMBERSTYLE = 0;
 846     private static final int CURRENCYSTYLE = 1;
 847     private static final int PERCENTSTYLE = 2;
 848     private static final int SCIENTIFICSTYLE = 3;
 849     private static final int INTEGERSTYLE = 4;
 850 
 851     /**
 852      * True if the grouping (i.e. thousands) separator is used when
 853      * formatting and parsing numbers.
 854      *
 855      * @serial
 856      * @see #isGroupingUsed
 857      */
 858     private boolean groupingUsed = true;
 859 
 860     /**
 861      * The maximum number of digits allowed in the integer portion of a
 862      * number.  <code>maxIntegerDigits</code> must be greater than or equal to
 863      * <code>minIntegerDigits</code>.


1034 
1035         /**
1036          * Creates a Field instance with the specified
1037          * name.
1038          *
1039          * @param name Name of the attribute
1040          */
1041         protected Field(String name) {
1042             super(name);
1043             if (this.getClass() == NumberFormat.Field.class) {
1044                 instanceMap.put(name, this);
1045             }
1046         }
1047 
1048         /**
1049          * Resolves instances being deserialized to the predefined constants.
1050          *
1051          * @throws InvalidObjectException if the constant could not be resolved.
1052          * @return resolved NumberFormat.Field constant
1053          */
1054         @Override
1055         protected Object readResolve() throws InvalidObjectException {
1056             if (this.getClass() != NumberFormat.Field.class) {
1057                 throw new InvalidObjectException("subclass didn't correctly implement readResolve");
1058             }
1059 
1060             Object instance = instanceMap.get(getName());
1061             if (instance != null) {
1062                 return instance;
1063             } else {
1064                 throw new InvalidObjectException("unknown attribute name");
1065             }
1066         }
1067 
1068         /**
1069          * Constant identifying the integer field.
1070          */
1071         public static final Field INTEGER = new Field("integer");
1072 
1073         /**
1074          * Constant identifying the fraction field.


1106         /**
1107          * Constant identifying the percent field.
1108          */
1109         public static final Field PERCENT = new Field("percent");
1110 
1111         /**
1112          * Constant identifying the permille field.
1113          */
1114         public static final Field PERMILLE = new Field("per mille");
1115 
1116         /**
1117          * Constant identifying the currency field.
1118          */
1119         public static final Field CURRENCY = new Field("currency");
1120 
1121         /**
1122          * Constant identifying the exponent sign field.
1123          */
1124         public static final Field EXPONENT_SIGN = new Field("exponent sign");
1125     }
































1126 }