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