1 /* 2 * Copyright (c) 1996, 2012, 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.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); 79 * </pre> 80 * </blockquote> 81 * If you are formatting multiple numbers, it is 82 * more efficient to get the format and use it multiple times so that 83 * the system doesn't have to fetch the information about the local 84 * language and country conventions multiple times. 85 * <blockquote> 86 * <pre> 87 * NumberFormat nf = NumberFormat.getInstance(); 88 * for (int i = 0; i < myNumber.length; ++i) { 89 * output.println(nf.format(myNumber[i]) + "; "); 90 * } 91 * </pre> 92 * </blockquote> 93 * To format a number for a different Locale, specify it in the 94 * call to <code>getInstance</code>. 95 * <blockquote> 96 * <pre> 97 * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH); 98 * </pre> 99 * </blockquote> 100 * You can also use a <code>NumberFormat</code> to parse numbers: 101 * <blockquote> 102 * <pre> 103 * myNumber = nf.parse(myString); 104 * </pre> 105 * </blockquote> 106 * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the 107 * normal number format. Use <code>getIntegerInstance</code> to get an 108 * integer number format. Use <code>getCurrencyInstance</code> to get the 109 * currency number format. And use <code>getPercentInstance</code> to get a 110 * format for displaying percentages. With this format, a fraction like 111 * 0.53 is displayed as 53%. 112 * 113 * <p> 114 * You can also control the display of numbers with such methods as 115 * <code>setMinimumFractionDigits</code>. 116 * If you want even more control over the format or parsing, 117 * or want to give your users more control, 118 * you can try casting the <code>NumberFormat</code> you get from the factory methods 119 * to a <code>DecimalFormat</code>. This will work for the vast majority 120 * of locales; just remember to put it in a <code>try</code> block in case you 121 * encounter an unusual one. 122 * 123 * <p> 124 * NumberFormat and DecimalFormat are designed such that some controls 125 * work for formatting and others work for parsing. The following is 126 * the detailed description for each these control methods, 127 * <p> 128 * setParseIntegerOnly : only affects parsing, e.g. 129 * if true, "3456.78" -> 3456 (and leaves the parse position just after index 6) 130 * if false, "3456.78" -> 3456.78 (and leaves the parse position just after index 8) 131 * This is independent of formatting. If you want to not show a decimal point 132 * where there might be no digits after the decimal point, use 133 * setDecimalSeparatorAlwaysShown. 134 * <p> 135 * setDecimalSeparatorAlwaysShown : only affects formatting, and only where 136 * there might be no digits after the decimal point, such as with a pattern 137 * like "#,##0.##", e.g., 138 * if true, 3456.00 -> "3,456." 139 * if false, 3456.00 -> "3456" 140 * This is independent of parsing. If you want parsing to stop at the decimal 141 * point, use setParseIntegerOnly. 142 * 143 * <p> 144 * You can also use forms of the <code>parse</code> and <code>format</code> 145 * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to 146 * allow you to: 147 * <ul> 148 * <li> progressively parse through pieces of a string 149 * <li> align the decimal point and other areas 150 * </ul> 151 * For example, you can align numbers in two ways: 152 * <ol> 153 * <li> If you are using a monospaced font with spacing for alignment, 154 * you can pass the <code>FieldPosition</code> in your format call, with 155 * <code>field</code> = <code>INTEGER_FIELD</code>. On output, 156 * <code>getEndIndex</code> will be set to the offset between the 157 * last character of the integer and the decimal. Add 158 * (desiredSpaceCount - getEndIndex) spaces at the front of the string. 159 * 160 * <li> If you are using proportional fonts, 161 * instead of padding with spaces, measure the width 162 * of the string in pixels from the start to <code>getEndIndex</code>. 163 * Then move the pen by 164 * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text. 165 * It also works where there is no decimal, but possibly additional 166 * characters at the end, e.g., with parentheses in negative 167 * numbers: "(12)" for -12. 168 * </ol> 169 * 170 * <h4><a name="synchronization">Synchronization</a></h4> 171 * 172 * <p> 173 * Number formats are generally not synchronized. 174 * It is recommended to create separate format instances for each thread. 175 * If multiple threads access a format concurrently, it must be synchronized 176 * externally. 177 * 178 * @see DecimalFormat 179 * @see ChoiceFormat 180 * @author Mark Davis 181 * @author Helena Shih 182 */ 183 public abstract class NumberFormat extends Format { 184 185 /** 186 * Field constant used to construct a FieldPosition object. Signifies that 187 * the position of the integer part of a formatted number should be returned. 188 * @see java.text.FieldPosition 189 */ 190 public static final int INTEGER_FIELD = 0; 191 192 /** 193 * Field constant used to construct a FieldPosition object. Signifies that 194 * the position of the fraction part of a formatted number should be returned. 195 * @see java.text.FieldPosition 196 */ 197 public static final int FRACTION_FIELD = 1; 198 199 /** 200 * Sole constructor. (For invocation by subclass constructors, typically 201 * implicit.) 202 */ 203 protected NumberFormat() { 204 } 205 206 /** 207 * Formats a number and appends the resulting text to the given string 208 * buffer. 209 * The number can be of any subclass of {@link java.lang.Number}. 210 * <p> 211 * This implementation extracts the number's value using 212 * {@link java.lang.Number#longValue()} for all integral type values that 213 * can be converted to <code>long</code> without loss of information, 214 * including <code>BigInteger</code> values with a 215 * {@link java.math.BigInteger#bitLength() bit length} of less than 64, 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 // Use fast-path for double result if that works 290 String result = fastFormat(number); 291 if (result != null) 292 return result; 293 294 return format(number, new StringBuffer(), 295 DontCareFieldPosition.INSTANCE).toString(); 296 } 297 298 /* 299 * fastFormat() is supposed to be implemented in concrete subclasses only. 300 * Default implem always returns null. 301 */ 302 String fastFormat(double number) { return null; } 303 304 /** 305 * Specialization of format. 306 * @exception ArithmeticException if rounding is needed with rounding 307 * mode being set to RoundingMode.UNNECESSARY 308 * @see java.text.Format#format 309 */ 310 public final String format(long number) { 311 return format(number, new StringBuffer(), 312 DontCareFieldPosition.INSTANCE).toString(); 313 } 314 315 /** 316 * Specialization of format. 317 * @exception ArithmeticException if rounding is needed with rounding 318 * mode being set to RoundingMode.UNNECESSARY 319 * @see java.text.Format#format 320 */ 321 public abstract StringBuffer format(double number, 322 StringBuffer toAppendTo, 323 FieldPosition pos); 324 325 /** 326 * Specialization of format. 327 * @exception ArithmeticException if rounding is needed with rounding 328 * mode being set to RoundingMode.UNNECESSARY 329 * @see java.text.Format#format 330 */ 331 public abstract StringBuffer format(long number, 332 StringBuffer toAppendTo, 333 FieldPosition pos); 334 335 /** 336 * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE, 337 * Long.MAX_VALUE] and with no decimals), otherwise a Double. 338 * If IntegerOnly is set, will stop at a decimal 339 * point (or equivalent; e.g., for rational numbers "1 2/3", will stop 340 * after the 1). 341 * Does not throw an exception; if no object can be parsed, index is 342 * unchanged! 343 * @see java.text.NumberFormat#isParseIntegerOnly 344 * @see java.text.Format#parseObject 345 */ 346 public abstract Number parse(String source, ParsePosition parsePosition); 347 348 /** 349 * Parses text from the beginning of the given string to produce a number. 350 * The method may not use the entire text of the given string. 351 * <p> 352 * See the {@link #parse(String, ParsePosition)} method for more information 353 * on number parsing. 354 * 355 * @param source A <code>String</code> whose beginning should be parsed. 356 * @return A <code>Number</code> parsed from the string. 357 * @exception ParseException if the beginning of the specified string 358 * cannot be parsed. 359 */ 360 public Number parse(String source) throws ParseException { 361 ParsePosition parsePosition = new ParsePosition(0); 362 Number result = parse(source, parsePosition); 363 if (parsePosition.index == 0) { 364 throw new ParseException("Unparseable number: \"" + source + "\"", 365 parsePosition.errorIndex); 366 } 367 return result; 368 } 369 370 /** 371 * Returns true if this format will parse numbers as integers only. 372 * For example in the English locale, with ParseIntegerOnly true, the 373 * string "1234." would be parsed as the integer value 1234 and parsing 374 * would stop at the "." character. Of course, the exact format accepted 375 * by the parse operation is locale dependant and determined by sub-classes 376 * of NumberFormat. 377 */ 378 public boolean isParseIntegerOnly() { 379 return parseIntegerOnly; 380 } 381 382 /** 383 * Sets whether or not numbers should be parsed as integers only. 384 * @see #isParseIntegerOnly 385 */ 386 public void setParseIntegerOnly(boolean value) { 387 parseIntegerOnly = value; 388 } 389 390 //============== Locale Stuff ===================== 391 392 /** 393 * Returns a general-purpose number format for the current default locale. 394 * This is the same as calling 395 * {@link #getNumberInstance() getNumberInstance()}. 396 */ 397 public final static NumberFormat getInstance() { 398 return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE); 399 } 400 401 /** 402 * Returns a general-purpose number format for the specified locale. 403 * This is the same as calling 404 * {@link #getNumberInstance(java.util.Locale) getNumberInstance(inLocale)}. 405 */ 406 public static NumberFormat getInstance(Locale inLocale) { 407 return getInstance(inLocale, NUMBERSTYLE); 408 } 409 410 /** 411 * Returns a general-purpose number format for the current default locale. 412 */ 413 public final static NumberFormat getNumberInstance() { 414 return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE); 415 } 416 417 /** 418 * Returns a general-purpose number format for the specified locale. 419 */ 420 public static NumberFormat getNumberInstance(Locale inLocale) { 421 return getInstance(inLocale, NUMBERSTYLE); 422 } 423 424 /** 425 * Returns an integer number format for the current default locale. The 426 * returned number format is configured to round floating point numbers 427 * to the nearest integer using half-even rounding (see {@link 428 * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting, 429 * and to parse only the integer part of an input string (see {@link 430 * #isParseIntegerOnly isParseIntegerOnly}). 431 * 432 * @see #getRoundingMode() 433 * @return a number format for integer values 434 * @since 1.4 435 */ 436 public final static NumberFormat getIntegerInstance() { 437 return getInstance(Locale.getDefault(Locale.Category.FORMAT), INTEGERSTYLE); 438 } 439 440 /** 441 * Returns an integer number format for the specified locale. The 442 * returned number format is configured to round floating point numbers 443 * to the nearest integer using half-even rounding (see {@link 444 * java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}) for formatting, 445 * and to parse only the integer part of an input string (see {@link 446 * #isParseIntegerOnly isParseIntegerOnly}). 447 * 448 * @see #getRoundingMode() 449 * @return a number format for integer values 450 * @since 1.4 451 */ 452 public static NumberFormat getIntegerInstance(Locale inLocale) { 453 return getInstance(inLocale, INTEGERSTYLE); 454 } 455 456 /** 457 * Returns a currency format for the current default locale. 458 */ 459 public final static NumberFormat getCurrencyInstance() { 460 return getInstance(Locale.getDefault(Locale.Category.FORMAT), CURRENCYSTYLE); 461 } 462 463 /** 464 * Returns a currency format for the specified locale. 465 */ 466 public static NumberFormat getCurrencyInstance(Locale inLocale) { 467 return getInstance(inLocale, CURRENCYSTYLE); 468 } 469 470 /** 471 * Returns a percentage format for the current default locale. 472 */ 473 public final static NumberFormat getPercentInstance() { 474 return getInstance(Locale.getDefault(Locale.Category.FORMAT), PERCENTSTYLE); 475 } 476 477 /** 478 * Returns a percentage format for the specified locale. 479 */ 480 public static NumberFormat getPercentInstance(Locale inLocale) { 481 return getInstance(inLocale, PERCENTSTYLE); 482 } 483 484 /** 485 * Returns a scientific format for the current default locale. 486 */ 487 /*public*/ final static NumberFormat getScientificInstance() { 488 return getInstance(Locale.getDefault(Locale.Category.FORMAT), SCIENTIFICSTYLE); 489 } 490 491 /** 492 * Returns a scientific format for the specified locale. 493 */ 494 /*public*/ static NumberFormat getScientificInstance(Locale inLocale) { 495 return getInstance(inLocale, SCIENTIFICSTYLE); 496 } 497 498 /** 499 * Returns an array of all locales for which the 500 * <code>get*Instance</code> methods of this class can return 501 * localized instances. 502 * The returned array represents the union of locales supported by the Java 503 * runtime and by installed 504 * {@link java.text.spi.NumberFormatProvider NumberFormatProvider} implementations. 505 * It must contain at least a <code>Locale</code> instance equal to 506 * {@link java.util.Locale#US Locale.US}. 507 * 508 * @return An array of locales for which localized 509 * <code>NumberFormat</code> instances are available. 510 */ 511 public static Locale[] getAvailableLocales() { 512 LocaleServiceProviderPool pool = 513 LocaleServiceProviderPool.getPool(NumberFormatProvider.class); 514 return pool.getAvailableLocales(); 515 } 516 517 /** 518 * Overrides hashCode. 519 */ 520 @Override 521 public int hashCode() { 522 return maximumIntegerDigits * 37 + maxFractionDigits; 523 // just enough fields for a reasonable distribution 524 } 525 526 /** 527 * Overrides equals. 528 */ 529 @Override 530 public boolean equals(Object obj) { 531 if (obj == null) { 532 return false; 533 } 534 if (this == obj) { 535 return true; 536 } 537 if (getClass() != obj.getClass()) { 538 return false; 539 } 540 NumberFormat other = (NumberFormat) obj; 541 return (maximumIntegerDigits == other.maximumIntegerDigits 542 && minimumIntegerDigits == other.minimumIntegerDigits 543 && maximumFractionDigits == other.maximumFractionDigits 544 && minimumFractionDigits == other.minimumFractionDigits 545 && groupingUsed == other.groupingUsed 546 && parseIntegerOnly == other.parseIntegerOnly); 547 } 548 549 /** 550 * Overrides Cloneable. 551 */ 552 @Override 553 public Object clone() { 554 NumberFormat other = (NumberFormat) super.clone(); 555 return other; 556 } 557 558 /** 559 * Returns true if grouping is used in this format. For example, in the 560 * English locale, with grouping on, the number 1234567 might be formatted 561 * as "1,234,567". The grouping separator as well as the size of each group 562 * is locale dependant and is determined by sub-classes of NumberFormat. 563 * @see #setGroupingUsed 564 */ 565 public boolean isGroupingUsed() { 566 return groupingUsed; 567 } 568 569 /** 570 * Set whether or not grouping will be used in this format. 571 * @see #isGroupingUsed 572 */ 573 public void setGroupingUsed(boolean newValue) { 574 groupingUsed = newValue; 575 } 576 577 /** 578 * Returns the maximum number of digits allowed in the integer portion of a 579 * number. 580 * @see #setMaximumIntegerDigits 581 */ 582 public int getMaximumIntegerDigits() { 583 return maximumIntegerDigits; 584 } 585 586 /** 587 * Sets the maximum number of digits allowed in the integer portion of a 588 * number. maximumIntegerDigits must be >= minimumIntegerDigits. If the 589 * new value for maximumIntegerDigits is less than the current value 590 * of minimumIntegerDigits, then minimumIntegerDigits will also be set to 591 * the new value. 592 * @param newValue the maximum number of integer digits to be shown; if 593 * less than zero, then zero is used. The concrete subclass may enforce an 594 * upper limit to this value appropriate to the numeric type being formatted. 595 * @see #getMaximumIntegerDigits 596 */ 597 public void setMaximumIntegerDigits(int newValue) { 598 maximumIntegerDigits = Math.max(0,newValue); 599 if (minimumIntegerDigits > maximumIntegerDigits) { 600 minimumIntegerDigits = maximumIntegerDigits; 601 } 602 } 603 604 /** 605 * Returns the minimum number of digits allowed in the integer portion of a 606 * number. 607 * @see #setMinimumIntegerDigits 608 */ 609 public int getMinimumIntegerDigits() { 610 return minimumIntegerDigits; 611 } 612 613 /** 614 * Sets the minimum number of digits allowed in the integer portion of a 615 * number. minimumIntegerDigits must be <= maximumIntegerDigits. If the 616 * new value for minimumIntegerDigits exceeds the current value 617 * of maximumIntegerDigits, then maximumIntegerDigits will also be set to 618 * the new value 619 * @param newValue the minimum number of integer digits to be shown; if 620 * less than zero, then zero is used. The concrete subclass may enforce an 621 * upper limit to this value appropriate to the numeric type being formatted. 622 * @see #getMinimumIntegerDigits 623 */ 624 public void setMinimumIntegerDigits(int newValue) { 625 minimumIntegerDigits = Math.max(0,newValue); 626 if (minimumIntegerDigits > maximumIntegerDigits) { 627 maximumIntegerDigits = minimumIntegerDigits; 628 } 629 } 630 631 /** 632 * Returns the maximum number of digits allowed in the fraction portion of a 633 * number. 634 * @see #setMaximumFractionDigits 635 */ 636 public int getMaximumFractionDigits() { 637 return maximumFractionDigits; 638 } 639 640 /** 641 * Sets the maximum number of digits allowed in the fraction portion of a 642 * number. maximumFractionDigits must be >= minimumFractionDigits. If the 643 * new value for maximumFractionDigits is less than the current value 644 * of minimumFractionDigits, then minimumFractionDigits will also be set to 645 * the new value. 646 * @param newValue the maximum number of fraction digits to be shown; if 647 * less than zero, then zero is used. The concrete subclass may enforce an 648 * upper limit to this value appropriate to the numeric type being formatted. 649 * @see #getMaximumFractionDigits 650 */ 651 public void setMaximumFractionDigits(int newValue) { 652 maximumFractionDigits = Math.max(0,newValue); 653 if (maximumFractionDigits < minimumFractionDigits) { 654 minimumFractionDigits = maximumFractionDigits; 655 } 656 } 657 658 /** 659 * Returns the minimum number of digits allowed in the fraction portion of a 660 * number. 661 * @see #setMinimumFractionDigits 662 */ 663 public int getMinimumFractionDigits() { 664 return minimumFractionDigits; 665 } 666 667 /** 668 * Sets the minimum number of digits allowed in the fraction portion of a 669 * number. minimumFractionDigits must be <= maximumFractionDigits. If the 670 * new value for minimumFractionDigits exceeds the current value 671 * of maximumFractionDigits, then maximumIntegerDigits will also be set to 672 * the new value 673 * @param newValue the minimum number of fraction digits to be shown; if 674 * less than zero, then zero is used. The concrete subclass may enforce an 675 * upper limit to this value appropriate to the numeric type being formatted. 676 * @see #getMinimumFractionDigits 677 */ 678 public void setMinimumFractionDigits(int newValue) { 679 minimumFractionDigits = Math.max(0,newValue); 680 if (maximumFractionDigits < minimumFractionDigits) { 681 maximumFractionDigits = minimumFractionDigits; 682 } 683 } 684 685 /** 686 * Gets the currency used by this number format when formatting 687 * currency values. The initial value is derived in a locale dependent 688 * way. The returned value may be null if no valid 689 * currency could be determined and no currency has been set using 690 * {@link #setCurrency(java.util.Currency) setCurrency}. 691 * <p> 692 * The default implementation throws 693 * <code>UnsupportedOperationException</code>. 694 * 695 * @return the currency used by this number format, or <code>null</code> 696 * @exception UnsupportedOperationException if the number format class 697 * doesn't implement currency formatting 698 * @since 1.4 699 */ 700 public Currency getCurrency() { 701 throw new UnsupportedOperationException(); 702 } 703 704 /** 705 * Sets the currency used by this number format when formatting 706 * currency values. This does not update the minimum or maximum 707 * number of fraction digits used by the number format. 708 * <p> 709 * The default implementation throws 710 * <code>UnsupportedOperationException</code>. 711 * 712 * @param currency the new currency to be used by this number format 713 * @exception UnsupportedOperationException if the number format class 714 * doesn't implement currency formatting 715 * @exception NullPointerException if <code>currency</code> is null 716 * @since 1.4 717 */ 718 public void setCurrency(Currency currency) { 719 throw new UnsupportedOperationException(); 720 } 721 722 /** 723 * Gets the {@link java.math.RoundingMode} used in this NumberFormat. 724 * The default implementation of this method in NumberFormat 725 * always 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 * @return The <code>RoundingMode</code> used for this NumberFormat. 732 * @see #setRoundingMode(RoundingMode) 733 * @since 1.6 734 */ 735 public RoundingMode getRoundingMode() { 736 throw new UnsupportedOperationException(); 737 } 738 739 /** 740 * Sets the {@link java.math.RoundingMode} used in this NumberFormat. 741 * The default implementation of this method in NumberFormat always 742 * throws {@link java.lang.UnsupportedOperationException}. 743 * Subclasses which handle different rounding modes should override 744 * this method. 745 * 746 * @exception UnsupportedOperationException The default implementation 747 * always throws this exception 748 * @exception NullPointerException if <code>roundingMode</code> is null 749 * @param roundingMode The <code>RoundingMode</code> to be used 750 * @see #getRoundingMode() 751 * @since 1.6 752 */ 753 public void setRoundingMode(RoundingMode roundingMode) { 754 throw new UnsupportedOperationException(); 755 } 756 757 // =======================privates=============================== 758 759 private static NumberFormat getInstance(Locale desiredLocale, 760 int choice) { 761 LocaleProviderAdapter adapter; 762 adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class, 763 desiredLocale); 764 NumberFormat numberFormat = getInstance(adapter, desiredLocale, choice); 765 if (numberFormat == null) { 766 numberFormat = getInstance(LocaleProviderAdapter.forJRE(), 767 desiredLocale, choice); 768 } 769 return numberFormat; 770 } 771 772 private static NumberFormat getInstance(LocaleProviderAdapter adapter, 773 Locale locale, int choice) { 774 NumberFormatProvider provider = adapter.getNumberFormatProvider(); 775 NumberFormat numberFormat = null; 776 switch (choice) { 777 case NUMBERSTYLE: 778 numberFormat = provider.getNumberInstance(locale); 779 break; 780 case PERCENTSTYLE: 781 numberFormat = provider.getPercentInstance(locale); 782 break; 783 case CURRENCYSTYLE: 784 numberFormat = provider.getCurrencyInstance(locale); 785 break; 786 case INTEGERSTYLE: 787 numberFormat = provider.getIntegerInstance(locale); 788 break; 789 } 790 return numberFormat; 791 } 792 793 /** 794 * First, read in the default serializable data. 795 * 796 * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that 797 * the stream was written by JDK 1.1, 798 * set the <code>int</code> fields such as <code>maximumIntegerDigits</code> 799 * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>, 800 * since the <code>int</code> fields were not present in JDK 1.1. 801 * Finally, set serialVersionOnStream back to the maximum allowed value so that 802 * default serialization will work properly if this object is streamed out again. 803 * 804 * <p>If <code>minimumIntegerDigits</code> is greater than 805 * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code> 806 * is greater than <code>maximumFractionDigits</code>, then the stream data 807 * is invalid and this method throws an <code>InvalidObjectException</code>. 808 * In addition, if any of these values is negative, then this method throws 809 * an <code>InvalidObjectException</code>. 810 * 811 * @since 1.2 812 */ 813 private void readObject(ObjectInputStream stream) 814 throws IOException, ClassNotFoundException 815 { 816 stream.defaultReadObject(); 817 if (serialVersionOnStream < 1) { 818 // Didn't have additional int fields, reassign to use them. 819 maximumIntegerDigits = maxIntegerDigits; 820 minimumIntegerDigits = minIntegerDigits; 821 maximumFractionDigits = maxFractionDigits; 822 minimumFractionDigits = minFractionDigits; 823 } 824 if (minimumIntegerDigits > maximumIntegerDigits || 825 minimumFractionDigits > maximumFractionDigits || 826 minimumIntegerDigits < 0 || minimumFractionDigits < 0) { 827 throw new InvalidObjectException("Digit count range invalid"); 828 } 829 serialVersionOnStream = currentSerialVersion; 830 } 831 832 /** 833 * Write out the default serializable data, after first setting 834 * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be 835 * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code> 836 * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility 837 * with the JDK 1.1 version of the stream format. 838 * 839 * @since 1.2 840 */ 841 private void writeObject(ObjectOutputStream stream) 842 throws IOException 843 { 844 maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? 845 Byte.MAX_VALUE : (byte)maximumIntegerDigits; 846 minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? 847 Byte.MAX_VALUE : (byte)minimumIntegerDigits; 848 maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? 849 Byte.MAX_VALUE : (byte)maximumFractionDigits; 850 minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? 851 Byte.MAX_VALUE : (byte)minimumFractionDigits; 852 stream.defaultWriteObject(); 853 } 854 855 // Constants used by factory methods to specify a style of format. 856 private static final int NUMBERSTYLE = 0; 857 private static final int CURRENCYSTYLE = 1; 858 private static final int PERCENTSTYLE = 2; 859 private static final int SCIENTIFICSTYLE = 3; 860 private static final int INTEGERSTYLE = 4; 861 862 /** 863 * True if the grouping (i.e. thousands) separator is used when 864 * formatting and parsing numbers. 865 * 866 * @serial 867 * @see #isGroupingUsed 868 */ 869 private boolean groupingUsed = true; 870 871 /** 872 * The maximum number of digits allowed in the integer portion of a 873 * number. <code>maxIntegerDigits</code> must be greater than or equal to 874 * <code>minIntegerDigits</code>. 875 * <p> 876 * <strong>Note:</strong> This field exists only for serialization 877 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 878 * <code>int</code> field <code>maximumIntegerDigits</code> is used instead. 879 * When writing to a stream, <code>maxIntegerDigits</code> is set to 880 * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>, 881 * whichever is smaller. When reading from a stream, this field is used 882 * only if <code>serialVersionOnStream</code> is less than 1. 883 * 884 * @serial 885 * @see #getMaximumIntegerDigits 886 */ 887 private byte maxIntegerDigits = 40; 888 889 /** 890 * The minimum number of digits allowed in the integer portion of a 891 * number. <code>minimumIntegerDigits</code> must be less than or equal to 892 * <code>maximumIntegerDigits</code>. 893 * <p> 894 * <strong>Note:</strong> This field exists only for serialization 895 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 896 * <code>int</code> field <code>minimumIntegerDigits</code> is used instead. 897 * When writing to a stream, <code>minIntegerDigits</code> is set to 898 * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>, 899 * whichever is smaller. When reading from a stream, this field is used 900 * only if <code>serialVersionOnStream</code> is less than 1. 901 * 902 * @serial 903 * @see #getMinimumIntegerDigits 904 */ 905 private byte minIntegerDigits = 1; 906 907 /** 908 * The maximum number of digits allowed in the fractional portion of a 909 * number. <code>maximumFractionDigits</code> must be greater than or equal to 910 * <code>minimumFractionDigits</code>. 911 * <p> 912 * <strong>Note:</strong> This field exists only for serialization 913 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 914 * <code>int</code> field <code>maximumFractionDigits</code> is used instead. 915 * When writing to a stream, <code>maxFractionDigits</code> is set to 916 * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>, 917 * whichever is smaller. When reading from a stream, this field is used 918 * only if <code>serialVersionOnStream</code> is less than 1. 919 * 920 * @serial 921 * @see #getMaximumFractionDigits 922 */ 923 private byte maxFractionDigits = 3; // invariant, >= minFractionDigits 924 925 /** 926 * The minimum number of digits allowed in the fractional portion of a 927 * number. <code>minimumFractionDigits</code> must be less than or equal to 928 * <code>maximumFractionDigits</code>. 929 * <p> 930 * <strong>Note:</strong> This field exists only for serialization 931 * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new 932 * <code>int</code> field <code>minimumFractionDigits</code> is used instead. 933 * When writing to a stream, <code>minFractionDigits</code> is set to 934 * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>, 935 * whichever is smaller. When reading from a stream, this field is used 936 * only if <code>serialVersionOnStream</code> is less than 1. 937 * 938 * @serial 939 * @see #getMinimumFractionDigits 940 */ 941 private byte minFractionDigits = 0; 942 943 /** 944 * True if this format will parse numbers as integers only. 945 * 946 * @serial 947 * @see #isParseIntegerOnly 948 */ 949 private boolean parseIntegerOnly = false; 950 951 // new fields for 1.2. byte is too small for integer digits. 952 953 /** 954 * The maximum number of digits allowed in the integer portion of a 955 * number. <code>maximumIntegerDigits</code> must be greater than or equal to 956 * <code>minimumIntegerDigits</code>. 957 * 958 * @serial 959 * @since 1.2 960 * @see #getMaximumIntegerDigits 961 */ 962 private int maximumIntegerDigits = 40; 963 964 /** 965 * The minimum number of digits allowed in the integer portion of a 966 * number. <code>minimumIntegerDigits</code> must be less than or equal to 967 * <code>maximumIntegerDigits</code>. 968 * 969 * @serial 970 * @since 1.2 971 * @see #getMinimumIntegerDigits 972 */ 973 private int minimumIntegerDigits = 1; 974 975 /** 976 * The maximum number of digits allowed in the fractional portion of a 977 * number. <code>maximumFractionDigits</code> must be greater than or equal to 978 * <code>minimumFractionDigits</code>. 979 * 980 * @serial 981 * @since 1.2 982 * @see #getMaximumFractionDigits 983 */ 984 private int maximumFractionDigits = 3; // invariant, >= minFractionDigits 985 986 /** 987 * The minimum number of digits allowed in the fractional portion of a 988 * number. <code>minimumFractionDigits</code> must be less than or equal to 989 * <code>maximumFractionDigits</code>. 990 * 991 * @serial 992 * @since 1.2 993 * @see #getMinimumFractionDigits 994 */ 995 private int minimumFractionDigits = 0; 996 997 static final int currentSerialVersion = 1; 998 999 /** 1000 * Describes the version of <code>NumberFormat</code> present on the stream. 1001 * Possible values are: 1002 * <ul> 1003 * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format. 1004 * In this version, the <code>int</code> fields such as 1005 * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code> 1006 * fields such as <code>maxIntegerDigits</code> are used instead. 1007 * 1008 * <li><b>1</b>: the 1.2 version of the stream format. The values of the 1009 * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored, 1010 * and the <code>int</code> fields such as <code>maximumIntegerDigits</code> 1011 * are used instead. 1012 * </ul> 1013 * When streaming out a <code>NumberFormat</code>, the most recent format 1014 * (corresponding to the highest allowable <code>serialVersionOnStream</code>) 1015 * is always written. 1016 * 1017 * @serial 1018 * @since 1.2 1019 */ 1020 private int serialVersionOnStream = currentSerialVersion; 1021 1022 // Removed "implements Cloneable" clause. Needs to update serialization 1023 // ID for backward compatibility. 1024 static final long serialVersionUID = -2308460125733713944L; 1025 1026 1027 // 1028 // class for AttributedCharacterIterator attributes 1029 // 1030 /** 1031 * Defines constants that are used as attribute keys in the 1032 * <code>AttributedCharacterIterator</code> returned 1033 * from <code>NumberFormat.formatToCharacterIterator</code> and as 1034 * field identifiers in <code>FieldPosition</code>. 1035 * 1036 * @since 1.4 1037 */ 1038 public static class Field extends Format.Field { 1039 1040 // Proclaim serial compatibility with 1.4 FCS 1041 private static final long serialVersionUID = 7494728892700160890L; 1042 1043 // table of all instances in this class, used by readResolve 1044 private static final Map<String, Field> instanceMap = new HashMap<>(11); 1045 1046 /** 1047 * Creates a Field instance with the specified 1048 * name. 1049 * 1050 * @param name Name of the attribute 1051 */ 1052 protected Field(String name) { 1053 super(name); 1054 if (this.getClass() == NumberFormat.Field.class) { 1055 instanceMap.put(name, this); 1056 } 1057 } 1058 1059 /** 1060 * Resolves instances being deserialized to the predefined constants. 1061 * 1062 * @throws InvalidObjectException if the constant could not be resolved. 1063 * @return resolved NumberFormat.Field constant 1064 */ 1065 @Override 1066 protected Object readResolve() throws InvalidObjectException { 1067 if (this.getClass() != NumberFormat.Field.class) { 1068 throw new InvalidObjectException("subclass didn't correctly implement readResolve"); 1069 } 1070 1071 Object instance = instanceMap.get(getName()); 1072 if (instance != null) { 1073 return instance; 1074 } else { 1075 throw new InvalidObjectException("unknown attribute name"); 1076 } 1077 } 1078 1079 /** 1080 * Constant identifying the integer field. 1081 */ 1082 public static final Field INTEGER = new Field("integer"); 1083 1084 /** 1085 * Constant identifying the fraction field. 1086 */ 1087 public static final Field FRACTION = new Field("fraction"); 1088 1089 /** 1090 * Constant identifying the exponent field. 1091 */ 1092 public static final Field EXPONENT = new Field("exponent"); 1093 1094 /** 1095 * Constant identifying the decimal separator field. 1096 */ 1097 public static final Field DECIMAL_SEPARATOR = 1098 new Field("decimal separator"); 1099 1100 /** 1101 * Constant identifying the sign field. 1102 */ 1103 public static final Field SIGN = new Field("sign"); 1104 1105 /** 1106 * Constant identifying the grouping separator field. 1107 */ 1108 public static final Field GROUPING_SEPARATOR = 1109 new Field("grouping separator"); 1110 1111 /** 1112 * Constant identifying the exponent symbol field. 1113 */ 1114 public static final Field EXPONENT_SYMBOL = new 1115 Field("exponent symbol"); 1116 1117 /** 1118 * Constant identifying the percent field. 1119 */ 1120 public static final Field PERCENT = new Field("percent"); 1121 1122 /** 1123 * Constant identifying the permille field. 1124 */ 1125 public static final Field PERMILLE = new Field("per mille"); 1126 1127 /** 1128 * Constant identifying the currency field. 1129 */ 1130 public static final Field CURRENCY = new Field("currency"); 1131 1132 /** 1133 * Constant identifying the exponent sign field. 1134 */ 1135 public static final Field EXPONENT_SIGN = new Field("exponent sign"); 1136 } 1137 }