1 /* 2 * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved 28 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved 29 * 30 * The original version of this source code and documentation is copyrighted 31 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These 32 * materials are provided under terms of a License Agreement between Taligent 33 * and Sun. This technology is protected by multiple US and International 34 * patents. This notice and attribution to Taligent may not be removed. 35 * Taligent is a registered trademark of Taligent, Inc. 36 * 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.Locale; 51 import java.util.Map; 52 import java.util.Objects; 53 import java.util.concurrent.atomic.AtomicInteger; 54 import java.util.concurrent.atomic.AtomicLong; 55 import sun.util.locale.provider.LocaleProviderAdapter; 56 import sun.util.locale.provider.LocaleServiceProviderPool; 57 58 /** 59 * <code>NumberFormat</code> is the abstract base class for all number 60 * formats. This class provides the interface for formatting and parsing 61 * numbers. <code>NumberFormat</code> also provides methods for determining 62 * which locales have number formats, and what their names are. 63 * 64 * <p> 65 * <code>NumberFormat</code> helps you to format and parse numbers for any locale. 66 * Your code can be completely independent of the locale conventions for 67 * decimal points, thousands-separators, or even the particular decimal 68 * digits used, or whether the number format is even decimal. 69 * 70 * <p> 71 * To format a number for the current Locale, use one of the factory 72 * class methods: 73 * <blockquote> 74 * <pre>{@code 75 * myString = NumberFormat.getInstance().format(myNumber); 76 * }</pre> 77 * </blockquote> 78 * If you are formatting multiple numbers, it is 79 * more efficient to get the format and use it multiple times so that 80 * the system doesn't have to fetch the information about the local 81 * language and country conventions multiple times. 82 * <blockquote> 83 * <pre>{@code 84 * NumberFormat nf = NumberFormat.getInstance(); 85 * for (int i = 0; i < myNumber.length; ++i) { 86 * output.println(nf.format(myNumber[i]) + "; "); 87 * } 88 * }</pre> 89 * </blockquote> 90 * To format a number for a different Locale, specify it in the 91 * call to <code>getInstance</code>. 92 * <blockquote> 93 * <pre>{@code 94 * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH); 95 * }</pre> 96 * </blockquote> 97 * 98 * <p>If the locale contains "nu" (numbers) and/or "rg" (region override) 99 * <a href="../util/Locale.html#def_locale_extension">Unicode extensions</a>, 100 * the decimal digits, and/or the country used for formatting are overridden. 101 * If both "nu" and "rg" are specified, the decimal digits from the "nu" 102 * extension supersedes the implicit one from the "rg" extension. 103 * 104 * <p>You can also use a {@code NumberFormat} to parse numbers: 105 * <blockquote> 106 * <pre>{@code 107 * myNumber = nf.parse(myString); 108 * }</pre> 109 * </blockquote> 110 * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the 111 * normal number format. Use <code>getIntegerInstance</code> to get an 112 * integer number format. Use <code>getCurrencyInstance</code> to get the 113 * currency number format. Use {@code getCompactNumberInstance} to get the 114 * compact number format to format a number in shorter form. For example, 115 * {@code 2000} can be formatted as {@code "2K"} in 116 * {@link java.util.Locale#US US locale}. Use <code>getPercentInstance</code> 117 * to get a format for displaying percentages. With this format, a fraction 118 * like 0.53 is displayed as 53%. 119 * 120 * <p> 121 * You can also control the display of numbers with such methods as 122 * <code>setMinimumFractionDigits</code>. 123 * If you want even more control over the format or parsing, 124 * or want to give your users more control, 125 * you can try casting the <code>NumberFormat</code> you get from the factory methods 126 * to a {@code DecimalFormat} or {@code CompactNumberFormat} depending on 127 * the factory method used. This will work for the vast majority of locales; 128 * just remember to put it in a <code>try</code> block in case you encounter 129 * an unusual one. 130 * 131 * <p> 132 * NumberFormat and DecimalFormat are designed such that some controls 133 * work for formatting and others work for parsing. The following is 134 * the detailed description for each these control methods, 135 * <p> 136 * setParseIntegerOnly : only affects parsing, e.g. 137 * if true, "3456.78" → 3456 (and leaves the parse position just after index 6) 138 * if false, "3456.78" → 3456.78 (and leaves the parse position just after index 8) 139 * This is independent of formatting. If you want to not show a decimal point 140 * where there might be no digits after the decimal point, use 141 * setDecimalSeparatorAlwaysShown. 142 * <p> 143 * setDecimalSeparatorAlwaysShown : only affects formatting, and only where 144 * there might be no digits after the decimal point, such as with a pattern 145 * like "#,##0.##", e.g., 146 * if true, 3456.00 → "3,456." 147 * if false, 3456.00 → "3456" 148 * This is independent of parsing. If you want parsing to stop at the decimal 149 * point, use setParseIntegerOnly. 150 * 151 * <p> 152 * You can also use forms of the <code>parse</code> and <code>format</code> 153 * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to 154 * allow you to: 155 * <ul> 156 * <li> progressively parse through pieces of a string 157 * <li> align the decimal point and other areas 158 * </ul> 159 * For example, you can align numbers in two ways: 160 * <ol> 161 * <li> If you are using a monospaced font with spacing for alignment, 162 * you can pass the <code>FieldPosition</code> in your format call, with 163 * <code>field</code> = <code>INTEGER_FIELD</code>. On output, 164 * <code>getEndIndex</code> will be set to the offset between the 165 * last character of the integer and the decimal. Add 166 * (desiredSpaceCount - getEndIndex) spaces at the front of the string. 167 * 168 * <li> If you are using proportional fonts, 169 * instead of padding with spaces, measure the width 170 * of the string in pixels from the start to <code>getEndIndex</code>. 171 * Then move the pen by 172 * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text. 173 * It also works where there is no decimal, but possibly additional 174 * characters at the end, e.g., with parentheses in negative 175 * numbers: "(12)" for -12. 176 * </ol> 177 * 178 * <h2><a id="synchronization">Synchronization</a></h2> 179 * 180 * <p> 181 * Number formats are generally not synchronized. 182 * It is recommended to create separate format instances for each thread. 183 * If multiple threads access a format concurrently, it must be synchronized 184 * externally. 185 * 186 * @implSpec The {@link #format(double, StringBuffer, FieldPosition)}, 187 * {@link #format(long, StringBuffer, FieldPosition)} and 188 * {@link #parse(String, ParsePosition)} methods may throw 189 * {@code NullPointerException}, if any of their parameter is {@code null}. 190 * The subclass may provide its own implementation and specification about 191 * {@code NullPointerException}. 192 * 193 * <p> 194 * The default implementation provides rounding modes defined 195 * in {@link java.math.RoundingMode} for formatting numbers. It 196 * uses the {@linkplain java.math.RoundingMode#HALF_EVEN 197 * round half-even algorithm}. To change the rounding mode use 198 * {@link #setRoundingMode(java.math.RoundingMode) setRoundingMode}. 199 * The {@code NumberFormat} returned by the static factory methods is 200 * configured to round floating point numbers using half-even 201 * rounding (see {@link java.math.RoundingMode#HALF_EVEN 202 * RoundingMode.HALF_EVEN}) for formatting. 203 * 204 * @see DecimalFormat 205 * @see ChoiceFormat 206 * @see CompactNumberFormat 207 * @author Mark Davis 208 * @author Helena Shih 209 * @since 1.1 210 */ 211 public abstract class NumberFormat extends Format { 212 213 /** 214 * Field constant used to construct a FieldPosition object. Signifies that 215 * the position of the integer part of a formatted number should be returned. 216 * @see java.text.FieldPosition 217 */ 218 public static final int INTEGER_FIELD = 0; 219 220 /** 221 * Field constant used to construct a FieldPosition object. Signifies that 222 * the position of the fraction part of a formatted number should be returned. 223 * @see java.text.FieldPosition 224 */ 225 public static final int FRACTION_FIELD = 1; 226 227 /** 228 * Sole constructor. (For invocation by subclass constructors, typically 229 * implicit.) 230 */ 231 protected NumberFormat() { 232 } 233 234 /** 235 * Formats a number and appends the resulting text to the given string 236 * buffer. 237 * The number can be of any subclass of {@link java.lang.Number}. 238 * <p> 239 * This implementation extracts the number's value using 240 * {@link java.lang.Number#longValue()} for all integral type values that 241 * can be converted to <code>long</code> without loss of information, 242 * including <code>BigInteger</code> values with a 243 * {@link java.math.BigInteger#bitLength() bit length} of less than 64, 244 * and {@link java.lang.Number#doubleValue()} for all other types. It 245 * then calls 246 * {@link #format(long,java.lang.StringBuffer,java.text.FieldPosition)} 247 * or {@link #format(double,java.lang.StringBuffer,java.text.FieldPosition)}. 248 * This may result in loss of magnitude information and precision for 249 * <code>BigInteger</code> and <code>BigDecimal</code> values. 250 * @param number the number to format 251 * @param toAppendTo the <code>StringBuffer</code> to which the formatted 252 * text is to be appended 253 * @param pos keeps track on the position of the field within the 254 * returned string. For example, for formatting a number 255 * {@code 1234567.89} in {@code Locale.US} locale, 256 * if the given {@code fieldPosition} is 257 * {@link NumberFormat#INTEGER_FIELD}, the begin index 258 * and end index of {@code fieldPosition} will be set 259 * to 0 and 9, respectively for the output string 260 * {@code 1,234,567.89}. 261 * @return the value passed in as <code>toAppendTo</code> 262 * @exception IllegalArgumentException if <code>number</code> is 263 * null or not an instance of <code>Number</code>. 264 * @exception NullPointerException if <code>toAppendTo</code> or 265 * <code>pos</code> is null 266 * @exception ArithmeticException if rounding is needed with rounding 267 * mode being set to RoundingMode.UNNECESSARY 268 * @see java.text.FieldPosition 269 */ 270 @Override 271 public StringBuffer format(Object number, 272 StringBuffer toAppendTo, 273 FieldPosition pos) { 274 if (number instanceof Long || number instanceof Integer || 275 number instanceof Short || number instanceof Byte || 276 number instanceof AtomicInteger || number instanceof AtomicLong || 277 (number instanceof BigInteger && 278 ((BigInteger)number).bitLength() < 64)) { 279 return format(((Number)number).longValue(), toAppendTo, pos); 280 } else if (number instanceof Number) { 281 return format(((Number)number).doubleValue(), toAppendTo, pos); 282 } else { 283 throw new IllegalArgumentException("Cannot format given Object as a Number"); 284 } 285 } 286 287 /** 288 * Parses text from a string to produce a <code>Number</code>. 289 * <p> 290 * The method attempts to parse text starting at the index given by 291 * <code>pos</code>. 292 * If parsing succeeds, then the index of <code>pos</code> is updated 293 * to the index after the last character used (parsing does not necessarily 294 * use all characters up to the end of the string), and the parsed 295 * number is returned. The updated <code>pos</code> can be used to 296 * indicate the starting point for the next call to this method. 297 * If an error occurs, then the index of <code>pos</code> is not 298 * changed, the error index of <code>pos</code> is set to the index of 299 * the character where the error occurred, and null is returned. 300 * <p> 301 * See the {@link #parse(String, ParsePosition)} method for more information 302 * on number parsing. 303 * 304 * @param source A <code>String</code>, part of which should be parsed. 305 * @param pos A <code>ParsePosition</code> object with index and error 306 * index information as described above. 307 * @return A <code>Number</code> parsed from the string. In case of 308 * error, returns null. 309 * @throws NullPointerException if {@code source} or {@code pos} is null. 310 */ 311 @Override 312 public final Object parseObject(String source, ParsePosition pos) { 313 return parse(source, pos); 314 } 315 316 /** 317 * Specialization of format. 318 * 319 * @param number the double number to format 320 * @return the formatted String 321 * @exception ArithmeticException if rounding is needed with rounding 322 * mode being set to RoundingMode.UNNECESSARY 323 * @see java.text.Format#format 324 */ 325 public final String format(double number) { 326 // Use fast-path for double result if that works 327 String result = fastFormat(number); 328 if (result != null) 329 return result; 330 331 return format(number, new StringBuffer(), 332 DontCareFieldPosition.INSTANCE).toString(); 333 } 334 335 /* 336 * fastFormat() is supposed to be implemented in concrete subclasses only. 337 * Default implem always returns null. 338 */ 339 String fastFormat(double number) { return null; } 340 341 /** 342 * Specialization of format. 343 * 344 * @param number the long number to format 345 * @return the formatted String 346 * @exception ArithmeticException if rounding is needed with rounding 347 * mode being set to RoundingMode.UNNECESSARY 348 * @see java.text.Format#format 349 */ 350 public final String format(long number) { 351 return format(number, new StringBuffer(), 352 DontCareFieldPosition.INSTANCE).toString(); 353 } 354 355 /** 356 * Specialization of format. 357 * 358 * @param number the double number to format 359 * @param toAppendTo the StringBuffer to which the formatted text is to be 360 * appended 361 * @param pos keeps track on the position of the field within the 362 * returned string. For example, for formatting a number 363 * {@code 1234567.89} in {@code Locale.US} locale, 364 * if the given {@code fieldPosition} is 365 * {@link NumberFormat#INTEGER_FIELD}, the begin index 366 * and end index of {@code fieldPosition} will be set 367 * to 0 and 9, respectively for the output string 368 * {@code 1,234,567.89}. 369 * @return the formatted StringBuffer 370 * @exception ArithmeticException if rounding is needed with rounding 371 * mode being set to RoundingMode.UNNECESSARY 372 * @see java.text.Format#format 373 */ 374 public abstract StringBuffer format(double number, 375 StringBuffer toAppendTo, 376 FieldPosition pos); 377 378 /** 379 * Specialization of format. 380 * 381 * @param number the long number to format 382 * @param toAppendTo the StringBuffer to which the formatted text is to be 383 * appended 384 * @param pos keeps track on the position of the field within the 385 * returned string. For example, for formatting a number 386 * {@code 123456789} in {@code Locale.US} locale, 387 * if the given {@code fieldPosition} is 388 * {@link NumberFormat#INTEGER_FIELD}, the begin index 389 * and end index of {@code fieldPosition} will be set 390 * to 0 and 11, respectively for the output string 391 * {@code 123,456,789}. 392 * @return the formatted StringBuffer 393 * @exception ArithmeticException if rounding is needed with rounding 394 * mode being set to RoundingMode.UNNECESSARY 395 * @see java.text.Format#format 396 */ 397 public abstract StringBuffer format(long number, 398 StringBuffer toAppendTo, 399 FieldPosition pos); 400 401 /** 402 * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE, 403 * Long.MAX_VALUE] and with no decimals), otherwise a Double. 404 * If IntegerOnly is set, will stop at a decimal 405 * point (or equivalent; e.g., for rational numbers "1 2/3", will stop 406 * after the 1). 407 * Does not throw an exception; if no object can be parsed, index is 408 * unchanged! 409 * 410 * @param source the String to parse 411 * @param parsePosition the parse position 412 * @return the parsed value 413 * @see java.text.NumberFormat#isParseIntegerOnly 414 * @see java.text.Format#parseObject 415 */ 416 public abstract Number parse(String source, ParsePosition parsePosition); 417 418 /** 419 * Parses text from the beginning of the given string to produce a number. 420 * The method may not use the entire text of the given string. 421 * <p> 422 * See the {@link #parse(String, ParsePosition)} method for more information 423 * on number parsing. 424 * 425 * @param source A <code>String</code> whose beginning should be parsed. 426 * @return A <code>Number</code> parsed from the string. 427 * @exception ParseException if the beginning of the specified string 428 * cannot be parsed. 429 */ 430 public Number parse(String source) throws ParseException { 431 ParsePosition parsePosition = new ParsePosition(0); 432 Number result = parse(source, parsePosition); 433 if (parsePosition.index == 0) { 434 throw new ParseException("Unparseable number: \"" + source + "\"", 435 parsePosition.errorIndex); 436 } 437 return result; 438 } 439 440 /** 441 * Returns true if this format will parse numbers as integers only. 442 * For example in the English locale, with ParseIntegerOnly true, the 443 * string "1234." would be parsed as the integer value 1234 and parsing 444 * would stop at the "." character. Of course, the exact format accepted 445 * by the parse operation is locale dependent and determined by sub-classes 446 * of NumberFormat. 447 * 448 * @return {@code true} if numbers should be parsed as integers only; 449 * {@code false} otherwise 450 */ 451 public boolean isParseIntegerOnly() { 452 return parseIntegerOnly; 453 } 454 455 /** 456 * Sets whether or not numbers should be parsed as integers only. 457 * 458 * @param value {@code true} if numbers should be parsed as integers only; 459 * {@code false} otherwise 460 * @see #isParseIntegerOnly 461 */ 462 public void setParseIntegerOnly(boolean value) { 463 parseIntegerOnly = value; 464 } 465 466 //============== Locale Stuff ===================== 467 468 /** 469 * Returns a general-purpose number format for the current default 470 * {@link java.util.Locale.Category#FORMAT FORMAT} locale. 471 * This is the same as calling 472 * {@link #getNumberInstance() getNumberInstance()}. 473 * 474 * @return the {@code NumberFormat} instance for general-purpose number 475 * formatting 476 */ 477 public static final NumberFormat getInstance() { 478 return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, NUMBERSTYLE); 479 } 480 481 /** 482 * Returns a general-purpose number format for the specified locale. 483 * This is the same as calling 484 * {@link #getNumberInstance(java.util.Locale) getNumberInstance(inLocale)}. 485 * 486 * @param inLocale the desired locale 487 * @return the {@code NumberFormat} instance for general-purpose number 488 * formatting 489 */ 490 public static NumberFormat getInstance(Locale inLocale) { 491 return getInstance(inLocale, null, NUMBERSTYLE); 492 } 493 494 /** 495 * Returns a general-purpose number format for the current default 496 * {@link java.util.Locale.Category#FORMAT FORMAT} locale. 497 * <p>This is equivalent to calling 498 * {@link #getNumberInstance(Locale) 499 * getNumberInstance(Locale.getDefault(Locale.Category.FORMAT))}. 500 * 501 * @return the {@code NumberFormat} instance for general-purpose number 502 * formatting 503 * @see java.util.Locale#getDefault(java.util.Locale.Category) 504 * @see java.util.Locale.Category#FORMAT 505 */ 506 public static final NumberFormat getNumberInstance() { 507 return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, NUMBERSTYLE); 508 } 509 510 /** 511 * Returns a general-purpose number format for the specified locale. 512 * 513 * @param inLocale the desired locale 514 * @return the {@code NumberFormat} instance for general-purpose number 515 * formatting 516 */ 517 public static NumberFormat getNumberInstance(Locale inLocale) { 518 return getInstance(inLocale, null, NUMBERSTYLE); 519 } 520 521 /** 522 * Returns an integer number format for the current default 523 * {@link java.util.Locale.Category#FORMAT FORMAT} locale. The 524 * returned number format is configured to round floating point numbers 525 * to the nearest integer using half-even rounding (see {@link 526 * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting, 527 * and to parse only the integer part of an input string (see {@link 528 * #isParseIntegerOnly isParseIntegerOnly}). 529 * <p>This is equivalent to calling 530 * {@link #getIntegerInstance(Locale) 531 * getIntegerInstance(Locale.getDefault(Locale.Category.FORMAT))}. 532 * 533 * @see #getRoundingMode() 534 * @see java.util.Locale#getDefault(java.util.Locale.Category) 535 * @see java.util.Locale.Category#FORMAT 536 * @return a number format for integer values 537 * @since 1.4 538 */ 539 public static final NumberFormat getIntegerInstance() { 540 return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, INTEGERSTYLE); 541 } 542 543 /** 544 * Returns an integer number format for the specified locale. The 545 * returned number format is configured to round floating point numbers 546 * to the nearest integer using half-even rounding (see {@link 547 * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting, 548 * and to parse only the integer part of an input string (see {@link 549 * #isParseIntegerOnly isParseIntegerOnly}). 550 * 551 * @param inLocale the desired locale 552 * @see #getRoundingMode() 553 * @return a number format for integer values 554 * @since 1.4 555 */ 556 public static NumberFormat getIntegerInstance(Locale inLocale) { 557 return getInstance(inLocale, null, INTEGERSTYLE); 558 } 559 560 /** 561 * Returns a currency format for the current default 562 * {@link java.util.Locale.Category#FORMAT FORMAT} locale. 563 * <p>This is equivalent to calling 564 * {@link #getCurrencyInstance(Locale) 565 * getCurrencyInstance(Locale.getDefault(Locale.Category.FORMAT))}. 566 * 567 * @return the {@code NumberFormat} instance for currency formatting 568 * @see java.util.Locale#getDefault(java.util.Locale.Category) 569 * @see java.util.Locale.Category#FORMAT 570 */ 571 public static final NumberFormat getCurrencyInstance() { 572 return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, CURRENCYSTYLE); 573 } 574 575 /** 576 * Returns a currency format for the specified locale. 577 * 578 * <p>If the specified locale contains the "{@code cf}" ( 579 * <a href="https://www.unicode.org/reports/tr35/tr35.html#UnicodeCurrencyFormatIdentifier"> 580 * currency format style</a>) 581 * <a href="../util/Locale.html#def_locale_extension">Unicode extension</a>, 582 * the returned currency format uses the style if it is available. 583 * Otherwise, the style uses the default "{@code standard}" currency format. 584 * For example, if the style designates "{@code account}", negative 585 * currency amounts use a pair of parentheses in some locales. 586 * 587 * @param inLocale the desired locale 588 * @return the {@code NumberFormat} instance for currency formatting 589 */ 590 public static NumberFormat getCurrencyInstance(Locale inLocale) { 591 return getInstance(inLocale, null, CURRENCYSTYLE); 592 } 593 594 /** 595 * Returns a percentage format for the current default 596 * {@link java.util.Locale.Category#FORMAT FORMAT} locale. 597 * <p>This is equivalent to calling 598 * {@link #getPercentInstance(Locale) 599 * getPercentInstance(Locale.getDefault(Locale.Category.FORMAT))}. 600 * 601 * @return the {@code NumberFormat} instance for percentage formatting 602 * @see java.util.Locale#getDefault(java.util.Locale.Category) 603 * @see java.util.Locale.Category#FORMAT 604 */ 605 public static final NumberFormat getPercentInstance() { 606 return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, PERCENTSTYLE); 607 } 608 609 /** 610 * Returns a percentage format for the specified locale. 611 * 612 * @param inLocale the desired locale 613 * @return the {@code NumberFormat} instance for percentage formatting 614 */ 615 public static NumberFormat getPercentInstance(Locale inLocale) { 616 return getInstance(inLocale, null, PERCENTSTYLE); 617 } 618 619 /** 620 * Returns a scientific format for the current default locale. 621 */ 622 /*public*/ final static NumberFormat getScientificInstance() { 623 return getInstance(Locale.getDefault(Locale.Category.FORMAT), null, SCIENTIFICSTYLE); 624 } 625 626 /** 627 * Returns a scientific format for the specified locale. 628 * 629 * @param inLocale the desired locale 630 */ 631 /*public*/ static NumberFormat getScientificInstance(Locale inLocale) { 632 return getInstance(inLocale, null, SCIENTIFICSTYLE); 633 } 634 635 /** 636 * Returns a compact number format for the default 637 * {@link java.util.Locale.Category#FORMAT FORMAT} locale with 638 * {@link NumberFormat.Style#SHORT "SHORT"} format style. 639 * 640 * @return A {@code NumberFormat} instance for compact number 641 * formatting 642 * 643 * @see CompactNumberFormat 644 * @see NumberFormat.Style 645 * @see java.util.Locale#getDefault(java.util.Locale.Category) 646 * @see java.util.Locale.Category#FORMAT 647 * @since 12 648 */ 649 public static NumberFormat getCompactNumberInstance() { 650 return getInstance(Locale.getDefault( 651 Locale.Category.FORMAT), NumberFormat.Style.SHORT, COMPACTSTYLE); 652 } 653 654 /** 655 * Returns a compact number format for the specified {@link java.util.Locale locale} 656 * and {@link NumberFormat.Style formatStyle}. 657 * 658 * @param locale the desired locale 659 * @param formatStyle the style for formatting a number 660 * @return A {@code NumberFormat} instance for compact number 661 * formatting 662 * @throws NullPointerException if {@code locale} or {@code formatStyle} 663 * is {@code null} 664 * 665 * @see CompactNumberFormat 666 * @see NumberFormat.Style 667 * @see java.util.Locale 668 * @since 12 669 */ 670 public static NumberFormat getCompactNumberInstance(Locale locale, 671 NumberFormat.Style formatStyle) { 672 673 Objects.requireNonNull(locale); 674 Objects.requireNonNull(formatStyle); 675 return getInstance(locale, formatStyle, COMPACTSTYLE); 676 } 677 678 /** 679 * Returns an array of all locales for which the 680 * <code>get*Instance</code> methods of this class can return 681 * localized instances. 682 * The returned array represents the union of locales supported by the Java 683 * runtime and by installed 684 * {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations. 685 * It must contain at least a <code>Locale</code> instance equal to 686 * {@link java.util.Locale#US Locale.US}. 687 * 688 * @return An array of locales for which localized 689 * <code>NumberFormat</code> instances are available. 690 */ 691 public static Locale[] getAvailableLocales() { 692 LocaleServiceProviderPool pool = 693 LocaleServiceProviderPool.getPool(NumberFormatProvider.class); 694 return pool.getAvailableLocales(); 695 } 696 697 /** 698 * Overrides hashCode. 699 */ 700 @Override 701 public int hashCode() { 702 return maximumIntegerDigits * 37 + maxFractionDigits; 703 // just enough fields for a reasonable distribution 704 } 705 706 /** 707 * Overrides equals. 708 */ 709 @Override 710 public boolean equals(Object obj) { 711 if (obj == null) { 712 return false; 713 } 714 if (this == obj) { 715 return true; 716 } 717 if (getClass() != obj.getClass()) { 718 return false; 719 } 720 NumberFormat other = (NumberFormat) obj; 721 return (maximumIntegerDigits == other.maximumIntegerDigits 722 && minimumIntegerDigits == other.minimumIntegerDigits 723 && maximumFractionDigits == other.maximumFractionDigits 724 && minimumFractionDigits == other.minimumFractionDigits 725 && groupingUsed == other.groupingUsed 726 && parseIntegerOnly == other.parseIntegerOnly); 727 } 728 729 /** 730 * Overrides Cloneable. 731 */ 732 @Override 733 public Object clone() { 734 NumberFormat other = (NumberFormat) super.clone(); 735 return other; 736 } 737 738 /** 739 * Returns true if grouping is used in this format. For example, in the 740 * English locale, with grouping on, the number 1234567 might be formatted 741 * as "1,234,567". The grouping separator as well as the size of each group 742 * is locale dependent and is determined by sub-classes of NumberFormat. 743 * 744 * @return {@code true} if grouping is used; 745 * {@code false} otherwise 746 * @see #setGroupingUsed 747 */ 748 public boolean isGroupingUsed() { 749 return groupingUsed; 750 } 751 752 /** 753 * Set whether or not grouping will be used in this format. 754 * 755 * @param newValue {@code true} if grouping is used; 756 * {@code false} otherwise 757 * @see #isGroupingUsed 758 */ 759 public void setGroupingUsed(boolean newValue) { 760 groupingUsed = newValue; 761 } 762 763 /** 764 * Returns the maximum number of digits allowed in the integer portion of a 765 * number. 766 * 767 * @return the maximum number of digits 768 * @see #setMaximumIntegerDigits 769 */ 770 public int getMaximumIntegerDigits() { 771 return maximumIntegerDigits; 772 } 773 774 /** 775 * Sets the maximum number of digits allowed in the integer portion of a 776 * number. maximumIntegerDigits must be ≥ minimumIntegerDigits. If the 777 * new value for maximumIntegerDigits is less than the current value 778 * of minimumIntegerDigits, then minimumIntegerDigits will also be set to 779 * the new value. 780 * 781 * @param newValue the maximum number of integer digits to be shown; if 782 * less than zero, then zero is used. The concrete subclass may enforce an 783 * upper limit to this value appropriate to the numeric type being formatted. 784 * @see #getMaximumIntegerDigits 785 */ 786 public void setMaximumIntegerDigits(int newValue) { 787 maximumIntegerDigits = Math.max(0,newValue); 788 if (minimumIntegerDigits > maximumIntegerDigits) { 789 minimumIntegerDigits = maximumIntegerDigits; 790 } 791 } 792 793 /** 794 * Returns the minimum number of digits allowed in the integer portion of a 795 * number. 796 * 797 * @return the minimum number of digits 798 * @see #setMinimumIntegerDigits 799 */ 800 public int getMinimumIntegerDigits() { 801 return minimumIntegerDigits; 802 } 803 804 /** 805 * Sets the minimum number of digits allowed in the integer portion of a 806 * number. minimumIntegerDigits must be ≤ maximumIntegerDigits. If the 807 * new value for minimumIntegerDigits exceeds the current value 808 * of maximumIntegerDigits, then maximumIntegerDigits will also be set to 809 * the new value 810 * 811 * @param newValue the minimum number of integer digits to be shown; if 812 * less than zero, then zero is used. The concrete subclass may enforce an 813 * upper limit to this value appropriate to the numeric type being formatted. 814 * @see #getMinimumIntegerDigits 815 */ 816 public void setMinimumIntegerDigits(int newValue) { 817 minimumIntegerDigits = Math.max(0,newValue); 818 if (minimumIntegerDigits > maximumIntegerDigits) { 819 maximumIntegerDigits = minimumIntegerDigits; 820 } 821 } 822 823 /** 824 * Returns the maximum number of digits allowed in the fraction portion of a 825 * number. 826 * 827 * @return the maximum number of digits. 828 * @see #setMaximumFractionDigits 829 */ 830 public int getMaximumFractionDigits() { 831 return maximumFractionDigits; 832 } 833 834 /** 835 * Sets the maximum number of digits allowed in the fraction portion of a 836 * number. maximumFractionDigits must be ≥ minimumFractionDigits. If the 837 * new value for maximumFractionDigits is less than the current value 838 * of minimumFractionDigits, then minimumFractionDigits will also be set to 839 * the new value. 840 * 841 * @param newValue the maximum number of fraction digits to be shown; if 842 * less than zero, then zero is used. The concrete subclass may enforce an 843 * upper limit to this value appropriate to the numeric type being formatted. 844 * @see #getMaximumFractionDigits 845 */ 846 public void setMaximumFractionDigits(int newValue) { 847 maximumFractionDigits = Math.max(0,newValue); 848 if (maximumFractionDigits < minimumFractionDigits) { 849 minimumFractionDigits = maximumFractionDigits; 850 } 851 } 852 853 /** 854 * Returns the minimum number of digits allowed in the fraction portion of a 855 * number. 856 * 857 * @return the minimum number of digits 858 * @see #setMinimumFractionDigits 859 */ 860 public int getMinimumFractionDigits() { 861 return minimumFractionDigits; 862 } 863 864 /** 865 * Sets the minimum number of digits allowed in the fraction portion of a 866 * number. minimumFractionDigits must be ≤ maximumFractionDigits. If the 867 * new value for minimumFractionDigits exceeds the current value 868 * of maximumFractionDigits, then maximumIntegerDigits will also be set to 869 * the new value 870 * 871 * @param newValue the minimum number of fraction digits to be shown; if 872 * less than zero, then zero is used. The concrete subclass may enforce an 873 * upper limit to this value appropriate to the numeric type being formatted. 874 * @see #getMinimumFractionDigits 875 */ 876 public void setMinimumFractionDigits(int newValue) { 877 minimumFractionDigits = Math.max(0,newValue); 878 if (maximumFractionDigits < minimumFractionDigits) { 879 maximumFractionDigits = minimumFractionDigits; 880 } 881 } 882 883 /** 884 * Gets the currency used by this number format when formatting 885 * currency values. The initial value is derived in a locale dependent 886 * way. The returned value may be null if no valid 887 * currency could be determined and no currency has been set using 888 * {@link #setCurrency(java.util.Currency) setCurrency}. 889 * <p> 890 * The default implementation throws 891 * <code>UnsupportedOperationException</code>. 892 * 893 * @return the currency used by this number format, or <code>null</code> 894 * @exception UnsupportedOperationException if the number format class 895 * doesn't implement currency formatting 896 * @since 1.4 897 */ 898 public Currency getCurrency() { 899 throw new UnsupportedOperationException(); 900 } 901 902 /** 903 * Sets the currency used by this number format when formatting 904 * currency values. This does not update the minimum or maximum 905 * number of fraction digits used by the number format. 906 * <p> 907 * The default implementation throws 908 * <code>UnsupportedOperationException</code>. 909 * 910 * @param currency the new currency to be used by this number format 911 * @exception UnsupportedOperationException if the number format class 912 * doesn't implement currency formatting 913 * @exception NullPointerException if <code>currency</code> is null 914 * @since 1.4 915 */ 916 public void setCurrency(Currency currency) { 917 throw new UnsupportedOperationException(); 918 } 919 920 /** 921 * Gets the {@link java.math.RoundingMode} used in this NumberFormat. 922 * The default implementation of this method in NumberFormat 923 * always throws {@link java.lang.UnsupportedOperationException}. 924 * Subclasses which handle different rounding modes should override 925 * this method. 926 * 927 * @exception UnsupportedOperationException The default implementation 928 * always throws this exception 929 * @return The <code>RoundingMode</code> used for this NumberFormat. 930 * @see #setRoundingMode(RoundingMode) 931 * @since 1.6 932 */ 933 public RoundingMode getRoundingMode() { 934 throw new UnsupportedOperationException(); 935 } 936 937 /** 938 * Sets the {@link java.math.RoundingMode} used in this NumberFormat. 939 * The default implementation of this method in NumberFormat always 940 * throws {@link java.lang.UnsupportedOperationException}. 941 * Subclasses which handle different rounding modes should override 942 * this method. 943 * 944 * @exception UnsupportedOperationException The default implementation 945 * always throws this exception 946 * @exception NullPointerException if <code>roundingMode</code> is null 947 * @param roundingMode The <code>RoundingMode</code> to be used 948 * @see #getRoundingMode() 949 * @since 1.6 950 */ 951 public void setRoundingMode(RoundingMode roundingMode) { 952 throw new UnsupportedOperationException(); 953 } 954 955 // =======================privates=============================== 956 957 private static NumberFormat getInstance(Locale desiredLocale, 958 Style formatStyle, int choice) { 959 LocaleProviderAdapter adapter; 960 adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class, 961 desiredLocale); 962 NumberFormat numberFormat = getInstance(adapter, desiredLocale, 963 formatStyle, choice); 964 if (numberFormat == null) { 965 numberFormat = getInstance(LocaleProviderAdapter.forJRE(), 966 desiredLocale, formatStyle, choice); 967 } 968 return numberFormat; 969 } 970 971 private static NumberFormat getInstance(LocaleProviderAdapter adapter, 972 Locale locale, Style formatStyle, 973 int choice) { 974 NumberFormatProvider provider = adapter.getNumberFormatProvider(); 975 NumberFormat numberFormat = null; 976 switch (choice) { 977 case NUMBERSTYLE: 978 numberFormat = provider.getNumberInstance(locale); 979 break; 980 case PERCENTSTYLE: 981 numberFormat = provider.getPercentInstance(locale); 982 break; 983 case CURRENCYSTYLE: 984 numberFormat = provider.getCurrencyInstance(locale); 985 break; 986 case INTEGERSTYLE: 987 numberFormat = provider.getIntegerInstance(locale); 988 break; 989 case COMPACTSTYLE: 990 numberFormat = provider.getCompactNumberInstance(locale, formatStyle); 991 break; 992 } 993 return numberFormat; 994 } 995 996 /** 997 * First, read in the default serializable data. 998 * 999 * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that 1000 * the stream was written by JDK 1.1, 1001 * set the <code>int</code> fields such as <code>maximumIntegerDigits</code> 1002 * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>, 1003 * since the <code>int</code> fields were not present in JDK 1.1. 1004 * Finally, set serialVersionOnStream back to the maximum allowed value so that 1005 * default serialization will work properly if this object is streamed out again. 1006 * 1007 * <p>If <code>minimumIntegerDigits</code> is greater than 1008 * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code> 1009 * is greater than <code>maximumFractionDigits</code>, then the stream data 1010 * is invalid and this method throws an <code>InvalidObjectException</code>. 1011 * In addition, if any of these values is negative, then this method throws 1012 * an <code>InvalidObjectException</code>. 1013 * 1014 * @since 1.2 1015 */ 1016 @java.io.Serial 1017 private void readObject(ObjectInputStream stream) 1018 throws IOException, ClassNotFoundException 1019 { 1020 stream.defaultReadObject(); 1021 if (serialVersionOnStream < 1) { 1022 // Didn't have additional int fields, reassign to use them. 1023 maximumIntegerDigits = maxIntegerDigits; 1024 minimumIntegerDigits = minIntegerDigits; 1025 maximumFractionDigits = maxFractionDigits; 1026 minimumFractionDigits = minFractionDigits; 1027 } 1028 if (minimumIntegerDigits > maximumIntegerDigits || 1029 minimumFractionDigits > maximumFractionDigits || 1030 minimumIntegerDigits < 0 || minimumFractionDigits < 0) { 1031 throw new InvalidObjectException("Digit count range invalid"); 1032 } 1033 serialVersionOnStream = currentSerialVersion; 1034 } 1035 1036 /** 1037 * Write out the default serializable data, after first setting 1038 * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be 1039 * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code> 1040 * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility 1041 * with the JDK 1.1 version of the stream format. 1042 * 1043 * @since 1.2 1044 */ 1045 @java.io.Serial 1046 private void writeObject(ObjectOutputStream stream) 1047 throws IOException 1048 { 1049 maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? 1050 Byte.MAX_VALUE : (byte)maximumIntegerDigits; 1051 minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? 1052 Byte.MAX_VALUE : (byte)minimumIntegerDigits; 1053 maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? 1054 Byte.MAX_VALUE : (byte)maximumFractionDigits; 1055 minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? 1056 Byte.MAX_VALUE : (byte)minimumFractionDigits; 1057 stream.defaultWriteObject(); 1058 } 1059 1060 // Constants used by factory methods to specify a style of format. 1061 private static final int NUMBERSTYLE = 0; 1062 private static final int CURRENCYSTYLE = 1; 1063 private static final int PERCENTSTYLE = 2; 1064 private static final int SCIENTIFICSTYLE = 3; 1065 private static final int INTEGERSTYLE = 4; 1066 private static final int COMPACTSTYLE = 5; 1067 1068 /** 1069 * True if the grouping (i.e. thousands) separator is used when 1070 * formatting and parsing numbers. 1071 * 1072 * @serial 1073 * @see #isGroupingUsed 1074 */ 1075 private boolean groupingUsed = true; 1076 1077 /** 1078 * The maximum number of digits allowed in the integer portion of a 1079 * number. <code>maxIntegerDigits</code> must be greater than or equal to 1080 * <code>minIntegerDigits</code>. 1081 * <p> 1082 * <strong>Note:</strong> This field exists only for serialization 1083 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 1084 * <code>int</code> field <code>maximumIntegerDigits</code> is used instead. 1085 * When writing to a stream, <code>maxIntegerDigits</code> is set to 1086 * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>, 1087 * whichever is smaller. When reading from a stream, this field is used 1088 * only if <code>serialVersionOnStream</code> is less than 1. 1089 * 1090 * @serial 1091 * @see #getMaximumIntegerDigits 1092 */ 1093 private byte maxIntegerDigits = 40; 1094 1095 /** 1096 * The minimum number of digits allowed in the integer portion of a 1097 * number. <code>minimumIntegerDigits</code> must be less than or equal to 1098 * <code>maximumIntegerDigits</code>. 1099 * <p> 1100 * <strong>Note:</strong> This field exists only for serialization 1101 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 1102 * <code>int</code> field <code>minimumIntegerDigits</code> is used instead. 1103 * When writing to a stream, <code>minIntegerDigits</code> is set to 1104 * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>, 1105 * whichever is smaller. When reading from a stream, this field is used 1106 * only if <code>serialVersionOnStream</code> is less than 1. 1107 * 1108 * @serial 1109 * @see #getMinimumIntegerDigits 1110 */ 1111 private byte minIntegerDigits = 1; 1112 1113 /** 1114 * The maximum number of digits allowed in the fractional portion of a 1115 * number. <code>maximumFractionDigits</code> must be greater than or equal to 1116 * <code>minimumFractionDigits</code>. 1117 * <p> 1118 * <strong>Note:</strong> This field exists only for serialization 1119 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 1120 * <code>int</code> field <code>maximumFractionDigits</code> is used instead. 1121 * When writing to a stream, <code>maxFractionDigits</code> is set to 1122 * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>, 1123 * whichever is smaller. When reading from a stream, this field is used 1124 * only if <code>serialVersionOnStream</code> is less than 1. 1125 * 1126 * @serial 1127 * @see #getMaximumFractionDigits 1128 */ 1129 private byte maxFractionDigits = 3; // invariant, >= minFractionDigits 1130 1131 /** 1132 * The minimum number of digits allowed in the fractional portion of a 1133 * number. <code>minimumFractionDigits</code> must be less than or equal to 1134 * <code>maximumFractionDigits</code>. 1135 * <p> 1136 * <strong>Note:</strong> This field exists only for serialization 1137 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 1138 * <code>int</code> field <code>minimumFractionDigits</code> is used instead. 1139 * When writing to a stream, <code>minFractionDigits</code> is set to 1140 * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>, 1141 * whichever is smaller. When reading from a stream, this field is used 1142 * only if <code>serialVersionOnStream</code> is less than 1. 1143 * 1144 * @serial 1145 * @see #getMinimumFractionDigits 1146 */ 1147 private byte minFractionDigits = 0; 1148 1149 /** 1150 * True if this format will parse numbers as integers only. 1151 * 1152 * @serial 1153 * @see #isParseIntegerOnly 1154 */ 1155 private boolean parseIntegerOnly = false; 1156 1157 // new fields for 1.2. byte is too small for integer digits. 1158 1159 /** 1160 * The maximum number of digits allowed in the integer portion of a 1161 * number. <code>maximumIntegerDigits</code> must be greater than or equal to 1162 * <code>minimumIntegerDigits</code>. 1163 * 1164 * @serial 1165 * @since 1.2 1166 * @see #getMaximumIntegerDigits 1167 */ 1168 private int maximumIntegerDigits = 40; 1169 1170 /** 1171 * The minimum number of digits allowed in the integer portion of a 1172 * number. <code>minimumIntegerDigits</code> must be less than or equal to 1173 * <code>maximumIntegerDigits</code>. 1174 * 1175 * @serial 1176 * @since 1.2 1177 * @see #getMinimumIntegerDigits 1178 */ 1179 private int minimumIntegerDigits = 1; 1180 1181 /** 1182 * The maximum number of digits allowed in the fractional portion of a 1183 * number. <code>maximumFractionDigits</code> must be greater than or equal to 1184 * <code>minimumFractionDigits</code>. 1185 * 1186 * @serial 1187 * @since 1.2 1188 * @see #getMaximumFractionDigits 1189 */ 1190 private int maximumFractionDigits = 3; // invariant, >= minFractionDigits 1191 1192 /** 1193 * The minimum number of digits allowed in the fractional portion of a 1194 * number. <code>minimumFractionDigits</code> must be less than or equal to 1195 * <code>maximumFractionDigits</code>. 1196 * 1197 * @serial 1198 * @since 1.2 1199 * @see #getMinimumFractionDigits 1200 */ 1201 private int minimumFractionDigits = 0; 1202 1203 static final int currentSerialVersion = 1; 1204 1205 /** 1206 * Describes the version of <code>NumberFormat</code> present on the stream. 1207 * Possible values are: 1208 * <ul> 1209 * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format. 1210 * In this version, the <code>int</code> fields such as 1211 * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code> 1212 * fields such as <code>maxIntegerDigits</code> are used instead. 1213 * 1214 * <li><b>1</b>: the 1.2 version of the stream format. The values of the 1215 * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored, 1216 * and the <code>int</code> fields such as <code>maximumIntegerDigits</code> 1217 * are used instead. 1218 * </ul> 1219 * When streaming out a <code>NumberFormat</code>, the most recent format 1220 * (corresponding to the highest allowable <code>serialVersionOnStream</code>) 1221 * is always written. 1222 * 1223 * @serial 1224 * @since 1.2 1225 */ 1226 private int serialVersionOnStream = currentSerialVersion; 1227 1228 // Removed "implements Cloneable" clause. Needs to update serialization 1229 // ID for backward compatibility. 1230 @java.io.Serial 1231 static final long serialVersionUID = -2308460125733713944L; 1232 1233 1234 // 1235 // class for AttributedCharacterIterator attributes 1236 // 1237 /** 1238 * Defines constants that are used as attribute keys in the 1239 * <code>AttributedCharacterIterator</code> returned 1240 * from <code>NumberFormat.formatToCharacterIterator</code> and as 1241 * field identifiers in <code>FieldPosition</code>. 1242 * 1243 * @since 1.4 1244 */ 1245 public static class Field extends Format.Field { 1246 1247 // Proclaim serial compatibility with 1.4 FCS 1248 @java.io.Serial 1249 private static final long serialVersionUID = 7494728892700160890L; 1250 1251 // table of all instances in this class, used by readResolve 1252 private static final Map<String, Field> instanceMap = new HashMap<>(11); 1253 1254 /** 1255 * Creates a Field instance with the specified 1256 * name. 1257 * 1258 * @param name Name of the attribute 1259 */ 1260 protected Field(String name) { 1261 super(name); 1262 if (this.getClass() == NumberFormat.Field.class) { 1263 instanceMap.put(name, this); 1264 } 1265 } 1266 1267 /** 1268 * Resolves instances being deserialized to the predefined constants. 1269 * 1270 * @throws InvalidObjectException if the constant could not be resolved. 1271 * @return resolved NumberFormat.Field constant 1272 */ 1273 @Override 1274 @java.io.Serial 1275 protected Object readResolve() throws InvalidObjectException { 1276 if (this.getClass() != NumberFormat.Field.class) { 1277 throw new InvalidObjectException("subclass didn't correctly implement readResolve"); 1278 } 1279 1280 Object instance = instanceMap.get(getName()); 1281 if (instance != null) { 1282 return instance; 1283 } else { 1284 throw new InvalidObjectException("unknown attribute name"); 1285 } 1286 } 1287 1288 /** 1289 * Constant identifying the integer field. 1290 */ 1291 public static final Field INTEGER = new Field("integer"); 1292 1293 /** 1294 * Constant identifying the fraction field. 1295 */ 1296 public static final Field FRACTION = new Field("fraction"); 1297 1298 /** 1299 * Constant identifying the exponent field. 1300 */ 1301 public static final Field EXPONENT = new Field("exponent"); 1302 1303 /** 1304 * Constant identifying the decimal separator field. 1305 */ 1306 public static final Field DECIMAL_SEPARATOR = 1307 new Field("decimal separator"); 1308 1309 /** 1310 * Constant identifying the sign field. 1311 */ 1312 public static final Field SIGN = new Field("sign"); 1313 1314 /** 1315 * Constant identifying the grouping separator field. 1316 */ 1317 public static final Field GROUPING_SEPARATOR = 1318 new Field("grouping separator"); 1319 1320 /** 1321 * Constant identifying the exponent symbol field. 1322 */ 1323 public static final Field EXPONENT_SYMBOL = new 1324 Field("exponent symbol"); 1325 1326 /** 1327 * Constant identifying the percent field. 1328 */ 1329 public static final Field PERCENT = new Field("percent"); 1330 1331 /** 1332 * Constant identifying the permille field. 1333 */ 1334 public static final Field PERMILLE = new Field("per mille"); 1335 1336 /** 1337 * Constant identifying the currency field. 1338 */ 1339 public static final Field CURRENCY = new Field("currency"); 1340 1341 /** 1342 * Constant identifying the exponent sign field. 1343 */ 1344 public static final Field EXPONENT_SIGN = new Field("exponent sign"); 1345 1346 /** 1347 * Constant identifying the prefix field. 1348 * 1349 * @since 12 1350 */ 1351 public static final Field PREFIX = new Field("prefix"); 1352 1353 /** 1354 * Constant identifying the suffix field. 1355 * 1356 * @since 12 1357 */ 1358 public static final Field SUFFIX = new Field("suffix"); 1359 } 1360 1361 /** 1362 * A number format style. 1363 * <p> 1364 * {@code Style} is an enum which represents the style for formatting 1365 * a number within a given {@code NumberFormat} instance. 1366 * 1367 * @see CompactNumberFormat 1368 * @see NumberFormat#getCompactNumberInstance(Locale, Style) 1369 * @since 12 1370 */ 1371 public enum Style { 1372 1373 /** 1374 * The {@code SHORT} number format style. 1375 */ 1376 SHORT, 1377 1378 /** 1379 * The {@code LONG} number format style. 1380 */ 1381 LONG 1382 1383 } 1384 }