1. /*
  2. * @(#)NumberFormat.java 1.60 03/01/27
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
  9. * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
  10. *
  11. * The original version of this source code and documentation is copyrighted
  12. * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  13. * materials are provided under terms of a License Agreement between Taligent
  14. * and Sun. This technology is protected by multiple US and International
  15. * patents. This notice and attribution to Taligent may not be removed.
  16. * Taligent is a registered trademark of Taligent, Inc.
  17. *
  18. */
  19. package java.text;
  20. import java.io.InvalidObjectException;
  21. import java.io.IOException;
  22. import java.io.ObjectInputStream;
  23. import java.io.ObjectOutputStream;
  24. import java.math.BigInteger;
  25. import java.util.Currency;
  26. import java.util.HashMap;
  27. import java.util.Hashtable;
  28. import java.util.Locale;
  29. import java.util.Map;
  30. import java.util.ResourceBundle;
  31. import sun.text.resources.LocaleData;
  32. /**
  33. * <code>NumberFormat</code> is the abstract base class for all number
  34. * formats. This class provides the interface for formatting and parsing
  35. * numbers. <code>NumberFormat</code> also provides methods for determining
  36. * which locales have number formats, and what their names are.
  37. *
  38. * <p>
  39. * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
  40. * Your code can be completely independent of the locale conventions for
  41. * decimal points, thousands-separators, or even the particular decimal
  42. * digits used, or whether the number format is even decimal.
  43. *
  44. * <p>
  45. * To format a number for the current Locale, use one of the factory
  46. * class methods:
  47. * <blockquote>
  48. * <pre>
  49. * myString = NumberFormat.getInstance().format(myNumber);
  50. * </pre>
  51. * </blockquote>
  52. * If you are formatting multiple numbers, it is
  53. * more efficient to get the format and use it multiple times so that
  54. * the system doesn't have to fetch the information about the local
  55. * language and country conventions multiple times.
  56. * <blockquote>
  57. * <pre>
  58. * NumberFormat nf = NumberFormat.getInstance();
  59. * for (int i = 0; i < a.length; ++i) {
  60. * output.println(nf.format(myNumber[i]) + "; ");
  61. * }
  62. * </pre>
  63. * </blockquote>
  64. * To format a number for a different Locale, specify it in the
  65. * call to <code>getInstance</code>.
  66. * <blockquote>
  67. * <pre>
  68. * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
  69. * </pre>
  70. * </blockquote>
  71. * You can also use a <code>NumberFormat</code> to parse numbers:
  72. * <blockquote>
  73. * <pre>
  74. * myNumber = nf.parse(myString);
  75. * </pre>
  76. * </blockquote>
  77. * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
  78. * normal number format. Use <code>getIntegerInstance</code> to get an
  79. * integer number format. Use <code>getCurrencyInstance</code> to get the
  80. * currency number format. And use <code>getPercentInstance</code> to get a
  81. * format for displaying percentages. With this format, a fraction like
  82. * 0.53 is displayed as 53%.
  83. *
  84. * <p>
  85. * You can also control the display of numbers with such methods as
  86. * <code>setMinimumFractionDigits</code>.
  87. * If you want even more control over the format or parsing,
  88. * or want to give your users more control,
  89. * you can try casting the <code>NumberFormat</code> you get from the factory methods
  90. * to a <code>DecimalFormat</code>. This will work for the vast majority
  91. * of locales; just remember to put it in a <code>try</code> block in case you
  92. * encounter an unusual one.
  93. *
  94. * <p>
  95. * NumberFormat and DecimalFormat are designed such that some controls
  96. * work for formatting and others work for parsing. The following is
  97. * the detailed description for each these control methods,
  98. * <p>
  99. * setParseIntegerOnly : only affects parsing, e.g.
  100. * if true, "3456.78" -> 3456 (and leaves the parse position just after index 6)
  101. * if false, "3456.78" -> 3456.78 (and leaves the parse position just after index 8)
  102. * This is independent of formatting. If you want to not show a decimal point
  103. * where there might be no digits after the decimal point, use
  104. * setDecimalSeparatorAlwaysShown.
  105. * <p>
  106. * setDecimalSeparatorAlwaysShown : only affects formatting, and only where
  107. * there might be no digits after the decimal point, such as with a pattern
  108. * like "#,##0.##", e.g.,
  109. * if true, 3456.00 -> "3,456."
  110. * if false, 3456.00 -> "3456"
  111. * This is independent of parsing. If you want parsing to stop at the decimal
  112. * point, use setParseIntegerOnly.
  113. *
  114. * <p>
  115. * You can also use forms of the <code>parse</code> and <code>format</code>
  116. * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
  117. * allow you to:
  118. * <ul>
  119. * <li> progressively parse through pieces of a string
  120. * <li> align the decimal point and other areas
  121. * </ul>
  122. * For example, you can align numbers in two ways:
  123. * <ol>
  124. * <li> If you are using a monospaced font with spacing for alignment,
  125. * you can pass the <code>FieldPosition</code> in your format call, with
  126. * <code>field</code> = <code>INTEGER_FIELD</code>. On output,
  127. * <code>getEndIndex</code> will be set to the offset between the
  128. * last character of the integer and the decimal. Add
  129. * (desiredSpaceCount - getEndIndex) spaces at the front of the string.
  130. *
  131. * <li> If you are using proportional fonts,
  132. * instead of padding with spaces, measure the width
  133. * of the string in pixels from the start to <code>getEndIndex</code>.
  134. * Then move the pen by
  135. * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
  136. * It also works where there is no decimal, but possibly additional
  137. * characters at the end, e.g., with parentheses in negative
  138. * numbers: "(12)" for -12.
  139. * </ol>
  140. *
  141. * <h4><a name="synchronization">Synchronization</a></h4>
  142. *
  143. * <p>
  144. * Number formats are generally not synchronized.
  145. * It is recommended to create separate format instances for each thread.
  146. * If multiple threads access a format concurrently, it must be synchronized
  147. * externally.
  148. *
  149. * @see DecimalFormat
  150. * @see ChoiceFormat
  151. * @version 1.60, 01/27/03
  152. * @author Mark Davis
  153. * @author Helena Shih
  154. */
  155. public abstract class NumberFormat extends Format {
  156. /**
  157. * Field constant used to construct a FieldPosition object. Signifies that
  158. * the position of the integer part of a formatted number should be returned.
  159. * @see java.text.FieldPosition
  160. */
  161. public static final int INTEGER_FIELD = 0;
  162. /**
  163. * Field constant used to construct a FieldPosition object. Signifies that
  164. * the position of the fraction part of a formatted number should be returned.
  165. * @see java.text.FieldPosition
  166. */
  167. public static final int FRACTION_FIELD = 1;
  168. /**
  169. * Formats an object to produce a string.
  170. * This general routines allows polymorphic parsing and
  171. * formatting for objects.
  172. * @param number the object to format
  173. * @param toAppendTo where the text is to be appended
  174. * @param pos On input: an alignment field, if desired.
  175. * On output: the offsets of the alignment field.
  176. * @return the value passed in as toAppendTo (this allows chaining,
  177. * as with StringBuffer.append())
  178. * @exception IllegalArgumentException when the Format cannot format the
  179. * given object.
  180. * @see java.text.FieldPosition
  181. */
  182. public final StringBuffer format(Object number,
  183. StringBuffer toAppendTo,
  184. FieldPosition pos)
  185. {
  186. if (number instanceof Long ||
  187. (number instanceof BigInteger && ((BigInteger)number).bitLength() < 64)) {
  188. return format(((Number)number).longValue(), toAppendTo, pos);
  189. }
  190. /* Here is the code that's required to get all the bits we can out of
  191. * BigDecimal into a long or double. In the interests of simplicity, we
  192. * don't use this code; we just convert BigDecimal values into doubles.
  193. * (Actually, to really do things right, you'd compare against both
  194. * Long.MIN_VALUE and Long.MAX_VALUE, since they differ in magnitude.)
  195. * Liu 6/98
  196. */
  197. // else if (number instanceof BigDecimal) {
  198. // BigDecimal bd = (BigDecimal)number;
  199. // try {
  200. // if (bd.setScale(0, BigDecimal.ROUND_UNNECESSARY).
  201. // abs().compareTo(new BigDecimal("9223372036854775807")) <= 0) {
  202. // return format(((Number)number).longValue(), toAppendTo, pos);
  203. // }
  204. // }
  205. // catch (ArithmeticException e) {}
  206. // return format(((Number)number).doubleValue(), toAppendTo, pos);
  207. // }
  208. else if (number instanceof Number) {
  209. return format(((Number)number).doubleValue(), toAppendTo, pos);
  210. }
  211. else {
  212. throw new IllegalArgumentException("Cannot format given Object as a Number");
  213. }
  214. }
  215. /**
  216. * Parses text from a string to produce a <code>Number</code>.
  217. * <p>
  218. * The method attempts to parse text starting at the index given by
  219. * <code>pos</code>.
  220. * If parsing succeeds, then the index of <code>pos</code> is updated
  221. * to the index after the last character used (parsing does not necessarily
  222. * use all characters up to the end of the string), and the parsed
  223. * number is returned. The updated <code>pos</code> can be used to
  224. * indicate the starting point for the next call to this method.
  225. * If an error occurs, then the index of <code>pos</code> is not
  226. * changed, the error index of <code>pos</code> is set to the index of
  227. * the character where the error occurred, and null is returned.
  228. * <p>
  229. * See the {@link #parse(String, ParsePosition)} method for more information
  230. * on number parsing.
  231. *
  232. * @param source A <code>String</code>, part of which should be parsed.
  233. * @param pos A <code>ParsePosition</code> object with index and error
  234. * index information as described above.
  235. * @return A <code>Number</code> parsed from the string. In case of
  236. * error, returns null.
  237. * @exception NullPointerException if <code>pos</code> is null.
  238. */
  239. public final Object parseObject(String source, ParsePosition pos) {
  240. return parse(source, pos);
  241. }
  242. /**
  243. * Specialization of format.
  244. * @see java.text.Format#format
  245. */
  246. public final String format(double number) {
  247. return format(number, new StringBuffer(),
  248. DontCareFieldPosition.INSTANCE).toString();
  249. }
  250. /**
  251. * Specialization of format.
  252. * @see java.text.Format#format
  253. */
  254. public final String format(long number) {
  255. return format(number, new StringBuffer(),
  256. DontCareFieldPosition.INSTANCE).toString();
  257. }
  258. /**
  259. * Specialization of format.
  260. * @see java.text.Format#format
  261. */
  262. public abstract StringBuffer format(double number,
  263. StringBuffer toAppendTo,
  264. FieldPosition pos);
  265. /**
  266. * Specialization of format.
  267. * @see java.text.Format#format
  268. */
  269. public abstract StringBuffer format(long number,
  270. StringBuffer toAppendTo,
  271. FieldPosition pos);
  272. /**
  273. * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
  274. * Long.MAX_VALUE] and with no decimals), otherwise a Double.
  275. * If IntegerOnly is set, will stop at a decimal
  276. * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
  277. * after the 1).
  278. * Does not throw an exception; if no object can be parsed, index is
  279. * unchanged!
  280. * @see java.text.NumberFormat#isParseIntegerOnly
  281. * @see java.text.Format#parseObject
  282. */
  283. public abstract Number parse(String source, ParsePosition parsePosition);
  284. /**
  285. * Parses text from the beginning of the given string to produce a number.
  286. * The method may not use the entire text of the given string.
  287. * <p>
  288. * See the {@link #parse(String, ParsePosition)} method for more information
  289. * on number parsing.
  290. *
  291. * @param source A <code>String</code> whose beginning should be parsed.
  292. * @return A <code>Number</code> parsed from the string.
  293. * @exception ParseException if the beginning of the specified string
  294. * cannot be parsed.
  295. */
  296. public Number parse(String source) throws ParseException {
  297. ParsePosition parsePosition = new ParsePosition(0);
  298. Number result = parse(source, parsePosition);
  299. if (parsePosition.index == 0) {
  300. throw new ParseException("Unparseable number: \"" + source + "\"",
  301. parsePosition.errorIndex);
  302. }
  303. return result;
  304. }
  305. /**
  306. * Returns true if this format will parse numbers as integers only.
  307. * For example in the English locale, with ParseIntegerOnly true, the
  308. * string "1234." would be parsed as the integer value 1234 and parsing
  309. * would stop at the "." character. Of course, the exact format accepted
  310. * by the parse operation is locale dependant and determined by sub-classes
  311. * of NumberFormat.
  312. */
  313. public boolean isParseIntegerOnly() {
  314. return parseIntegerOnly;
  315. }
  316. /**
  317. * Sets whether or not numbers should be parsed as integers only.
  318. * @see #isParseIntegerOnly
  319. */
  320. public void setParseIntegerOnly(boolean value) {
  321. parseIntegerOnly = value;
  322. }
  323. //============== Locale Stuff =====================
  324. /**
  325. * Returns the default number format for the current default locale.
  326. * The default format is one of the styles provided by the other
  327. * factory methods: getNumberInstance, getIntegerInstance,
  328. * getCurrencyInstance or getPercentInstance.
  329. * Exactly which one is locale dependant.
  330. */
  331. public final static NumberFormat getInstance() {
  332. return getInstance(Locale.getDefault(), NUMBERSTYLE);
  333. }
  334. /**
  335. * Returns the default number format for the specified locale.
  336. * The default format is one of the styles provided by the other
  337. * factory methods: getNumberInstance, getIntegerInstance,
  338. * getCurrencyInstance or getPercentInstance.
  339. * Exactly which one is locale dependant.
  340. */
  341. public static NumberFormat getInstance(Locale inLocale) {
  342. return getInstance(inLocale, NUMBERSTYLE);
  343. }
  344. /**
  345. * Returns a general-purpose number format for the current default locale.
  346. */
  347. public final static NumberFormat getNumberInstance() {
  348. return getInstance(Locale.getDefault(), NUMBERSTYLE);
  349. }
  350. /**
  351. * Returns a general-purpose number format for the specified locale.
  352. */
  353. public static NumberFormat getNumberInstance(Locale inLocale) {
  354. return getInstance(inLocale, NUMBERSTYLE);
  355. }
  356. /**
  357. * Returns an integer number format for the current default locale. The
  358. * returned number format is configured to round floating point numbers
  359. * to the nearest integer using IEEE half-even rounding (see {@link
  360. * java.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
  361. * and to parse only the integer part of an input string (see {@link
  362. * #isParseIntegerOnly isParseIntegerOnly}).
  363. *
  364. * @return a number format for integer values
  365. * @since 1.4
  366. */
  367. public final static NumberFormat getIntegerInstance() {
  368. return getInstance(Locale.getDefault(), INTEGERSTYLE);
  369. }
  370. /**
  371. * Returns an integer number format for the specified locale. The
  372. * returned number format is configured to round floating point numbers
  373. * to the nearest integer using IEEE half-even rounding (see {@link
  374. * java.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
  375. * and to parse only the integer part of an input string (see {@link
  376. * #isParseIntegerOnly isParseIntegerOnly}).
  377. *
  378. * @param inLocale the locale for which a number format is needed
  379. * @return a number format for integer values
  380. * @since 1.4
  381. */
  382. public static NumberFormat getIntegerInstance(Locale inLocale) {
  383. return getInstance(inLocale, INTEGERSTYLE);
  384. }
  385. /**
  386. * Returns a currency format for the current default locale.
  387. */
  388. public final static NumberFormat getCurrencyInstance() {
  389. return getInstance(Locale.getDefault(), CURRENCYSTYLE);
  390. }
  391. /**
  392. * Returns a currency format for the specified locale.
  393. */
  394. public static NumberFormat getCurrencyInstance(Locale inLocale) {
  395. return getInstance(inLocale, CURRENCYSTYLE);
  396. }
  397. /**
  398. * Returns a percentage format for the current default locale.
  399. */
  400. public final static NumberFormat getPercentInstance() {
  401. return getInstance(Locale.getDefault(), PERCENTSTYLE);
  402. }
  403. /**
  404. * Returns a percentage format for the specified locale.
  405. */
  406. public static NumberFormat getPercentInstance(Locale inLocale) {
  407. return getInstance(inLocale, PERCENTSTYLE);
  408. }
  409. /**
  410. * Returns a scientific format for the current default locale.
  411. */
  412. /*public*/ final static NumberFormat getScientificInstance() {
  413. return getInstance(Locale.getDefault(), SCIENTIFICSTYLE);
  414. }
  415. /**
  416. * Returns a scientific format for the specified locale.
  417. */
  418. /*public*/ static NumberFormat getScientificInstance(Locale inLocale) {
  419. return getInstance(inLocale, SCIENTIFICSTYLE);
  420. }
  421. /**
  422. * Get the set of Locales for which NumberFormats are installed
  423. * @return available locales
  424. */
  425. public static Locale[] getAvailableLocales() {
  426. return LocaleData.getAvailableLocales("NumberPatterns");
  427. }
  428. /**
  429. * Overrides hashCode
  430. */
  431. public int hashCode() {
  432. return maximumIntegerDigits * 37 + maxFractionDigits;
  433. // just enough fields for a reasonable distribution
  434. }
  435. /**
  436. * Overrides equals
  437. */
  438. public boolean equals(Object obj) {
  439. if (obj == null) return false;
  440. if (this == obj)
  441. return true;
  442. if (getClass() != obj.getClass())
  443. return false;
  444. NumberFormat other = (NumberFormat) obj;
  445. return (maximumIntegerDigits == other.maximumIntegerDigits
  446. && minimumIntegerDigits == other.minimumIntegerDigits
  447. && maximumFractionDigits == other.maximumFractionDigits
  448. && minimumFractionDigits == other.minimumFractionDigits
  449. && groupingUsed == other.groupingUsed
  450. && parseIntegerOnly == other.parseIntegerOnly);
  451. }
  452. /**
  453. * Overrides Cloneable
  454. */
  455. public Object clone()
  456. {
  457. NumberFormat other = (NumberFormat) super.clone();
  458. return other;
  459. }
  460. /**
  461. * Returns true if grouping is used in this format. For example, in the
  462. * English locale, with grouping on, the number 1234567 might be formatted
  463. * as "1,234,567". The grouping separator as well as the size of each group
  464. * is locale dependant and is determined by sub-classes of NumberFormat.
  465. * @see #setGroupingUsed
  466. */
  467. public boolean isGroupingUsed() {
  468. return groupingUsed;
  469. }
  470. /**
  471. * Set whether or not grouping will be used in this format.
  472. * @see #isGroupingUsed
  473. */
  474. public void setGroupingUsed(boolean newValue) {
  475. groupingUsed = newValue;
  476. }
  477. /**
  478. * Returns the maximum number of digits allowed in the integer portion of a
  479. * number.
  480. * @see #setMaximumIntegerDigits
  481. */
  482. public int getMaximumIntegerDigits() {
  483. return maximumIntegerDigits;
  484. }
  485. /**
  486. * Sets the maximum number of digits allowed in the integer portion of a
  487. * number. maximumIntegerDigits must be >= minimumIntegerDigits. If the
  488. * new value for maximumIntegerDigits is less than the current value
  489. * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
  490. * the new value.
  491. * @param newValue the maximum number of integer digits to be shown; if
  492. * less than zero, then zero is used. The concrete subclass may enforce an
  493. * upper limit to this value appropriate to the numeric type being formatted.
  494. * @see #getMaximumIntegerDigits
  495. */
  496. public void setMaximumIntegerDigits(int newValue) {
  497. maximumIntegerDigits = Math.max(0,newValue);
  498. if (minimumIntegerDigits > maximumIntegerDigits)
  499. minimumIntegerDigits = maximumIntegerDigits;
  500. }
  501. /**
  502. * Returns the minimum number of digits allowed in the integer portion of a
  503. * number.
  504. * @see #setMinimumIntegerDigits
  505. */
  506. public int getMinimumIntegerDigits() {
  507. return minimumIntegerDigits;
  508. }
  509. /**
  510. * Sets the minimum number of digits allowed in the integer portion of a
  511. * number. minimumIntegerDigits must be <= maximumIntegerDigits. If the
  512. * new value for minimumIntegerDigits exceeds the current value
  513. * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
  514. * the new value
  515. * @param newValue the minimum number of integer digits to be shown; if
  516. * less than zero, then zero is used. The concrete subclass may enforce an
  517. * upper limit to this value appropriate to the numeric type being formatted.
  518. * @see #getMinimumIntegerDigits
  519. */
  520. public void setMinimumIntegerDigits(int newValue) {
  521. minimumIntegerDigits = Math.max(0,newValue);
  522. if (minimumIntegerDigits > maximumIntegerDigits)
  523. maximumIntegerDigits = minimumIntegerDigits;
  524. }
  525. /**
  526. * Returns the maximum number of digits allowed in the fraction portion of a
  527. * number.
  528. * @see #setMaximumFractionDigits
  529. */
  530. public int getMaximumFractionDigits() {
  531. return maximumFractionDigits;
  532. }
  533. /**
  534. * Sets the maximum number of digits allowed in the fraction portion of a
  535. * number. maximumFractionDigits must be >= minimumFractionDigits. If the
  536. * new value for maximumFractionDigits is less than the current value
  537. * of minimumFractionDigits, then minimumFractionDigits will also be set to
  538. * the new value.
  539. * @param newValue the maximum number of fraction digits to be shown; if
  540. * less than zero, then zero is used. The concrete subclass may enforce an
  541. * upper limit to this value appropriate to the numeric type being formatted.
  542. * @see #getMaximumFractionDigits
  543. */
  544. public void setMaximumFractionDigits(int newValue) {
  545. maximumFractionDigits = Math.max(0,newValue);
  546. if (maximumFractionDigits < minimumFractionDigits)
  547. minimumFractionDigits = maximumFractionDigits;
  548. }
  549. /**
  550. * Returns the minimum number of digits allowed in the fraction portion of a
  551. * number.
  552. * @see #setMinimumFractionDigits
  553. */
  554. public int getMinimumFractionDigits() {
  555. return minimumFractionDigits;
  556. }
  557. /**
  558. * Sets the minimum number of digits allowed in the fraction portion of a
  559. * number. minimumFractionDigits must be <= maximumFractionDigits. If the
  560. * new value for minimumFractionDigits exceeds the current value
  561. * of maximumFractionDigits, then maximumIntegerDigits will also be set to
  562. * the new value
  563. * @param newValue the minimum number of fraction digits to be shown; if
  564. * less than zero, then zero is used. The concrete subclass may enforce an
  565. * upper limit to this value appropriate to the numeric type being formatted.
  566. * @see #getMinimumFractionDigits
  567. */
  568. public void setMinimumFractionDigits(int newValue) {
  569. minimumFractionDigits = Math.max(0,newValue);
  570. if (maximumFractionDigits < minimumFractionDigits)
  571. maximumFractionDigits = minimumFractionDigits;
  572. }
  573. /**
  574. * Gets the currency used by this number format when formatting
  575. * currency values. The initial value is derived in a locale dependent
  576. * way. The returned value may be null if no valid
  577. * currency could be determined and no currency has been set using
  578. * {@link #setCurrency(java.util.Currency) setCurrency}.
  579. * <p>
  580. * The default implementation throws
  581. * <code>UnsupportedOperationException</code>.
  582. *
  583. * @return the currency used by this number format, or <code>null</code>
  584. * @exception UnsupportedOperationException if the number format class
  585. * doesn't implement currency formatting
  586. * @since 1.4
  587. */
  588. public Currency getCurrency() {
  589. throw new UnsupportedOperationException();
  590. }
  591. /**
  592. * Sets the currency used by this number format when formatting
  593. * currency values. This does not update the minimum or maximum
  594. * number of fraction digits used by the number format.
  595. * <p>
  596. * The default implementation throws
  597. * <code>UnsupportedOperationException</code>.
  598. *
  599. * @param currency the new currency to be used by this number format
  600. * @exception UnsupportedOperationException if the number format class
  601. * doesn't implement currency formatting
  602. * @exception NullPointerException if <code>currency</code> is null
  603. * @since 1.4
  604. */
  605. public void setCurrency(Currency currency) {
  606. throw new UnsupportedOperationException();
  607. }
  608. // =======================privates===============================
  609. private static NumberFormat getInstance(Locale desiredLocale,
  610. int choice) {
  611. /* try the cache first */
  612. String[] numberPatterns = (String[])cachedLocaleData.get(desiredLocale);
  613. if (numberPatterns == null) { /* cache miss */
  614. ResourceBundle resource = LocaleData.getLocaleElements(desiredLocale);
  615. numberPatterns = resource.getStringArray("NumberPatterns");
  616. /* update cache */
  617. cachedLocaleData.put(desiredLocale, numberPatterns);
  618. }
  619. DecimalFormatSymbols symbols = new DecimalFormatSymbols(desiredLocale);
  620. int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : choice;
  621. DecimalFormat format = new DecimalFormat(numberPatterns[entry], symbols);
  622. if (choice == INTEGERSTYLE) {
  623. format.setMaximumFractionDigits(0);
  624. format.setDecimalSeparatorAlwaysShown(false);
  625. format.setParseIntegerOnly(true);
  626. } else if (choice == CURRENCYSTYLE) {
  627. format.adjustForCurrencyDefaultFractionDigits();
  628. }
  629. return format;
  630. }
  631. /**
  632. * First, read in the default serializable data.
  633. *
  634. * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
  635. * the stream was written by JDK 1.1,
  636. * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  637. * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
  638. * since the <code>int</code> fields were not present in JDK 1.1.
  639. * Finally, set serialVersionOnStream back to the maximum allowed value so that
  640. * default serialization will work properly if this object is streamed out again.
  641. *
  642. * <p>If <code>minimumIntegerDigits</code> is greater than
  643. * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code>
  644. * is greater than <code>maximumFractionDigits</code>, then the stream data
  645. * is invalid and this method throws an <code>InvalidObjectException</code>.
  646. * In addition, if any of these values is negative, then this method throws
  647. * an <code>InvalidObjectException</code>.
  648. *
  649. * @since 1.2
  650. */
  651. private void readObject(ObjectInputStream stream)
  652. throws IOException, ClassNotFoundException
  653. {
  654. stream.defaultReadObject();
  655. if (serialVersionOnStream < 1) {
  656. // Didn't have additional int fields, reassign to use them.
  657. maximumIntegerDigits = maxIntegerDigits;
  658. minimumIntegerDigits = minIntegerDigits;
  659. maximumFractionDigits = maxFractionDigits;
  660. minimumFractionDigits = minFractionDigits;
  661. }
  662. if (minimumIntegerDigits > maximumIntegerDigits ||
  663. minimumFractionDigits > maximumFractionDigits ||
  664. minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
  665. throw new InvalidObjectException("Digit count range invalid");
  666. }
  667. serialVersionOnStream = currentSerialVersion;
  668. }
  669. /**
  670. * Write out the default serializable data, after first setting
  671. * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
  672. * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  673. * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
  674. * with the JDK 1.1 version of the stream format.
  675. *
  676. * @since 1.2
  677. */
  678. private void writeObject(ObjectOutputStream stream)
  679. throws IOException
  680. {
  681. maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  682. (byte)maximumIntegerDigits;
  683. minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  684. (byte)minimumIntegerDigits;
  685. maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  686. (byte)maximumFractionDigits;
  687. minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  688. (byte)minimumFractionDigits;
  689. stream.defaultWriteObject();
  690. }
  691. /**
  692. * Cache to hold the NumberPatterns of a Locale.
  693. */
  694. private static final Hashtable cachedLocaleData = new Hashtable(3);
  695. // Constants used by factory methods to specify a style of format.
  696. private static final int NUMBERSTYLE = 0;
  697. private static final int CURRENCYSTYLE = 1;
  698. private static final int PERCENTSTYLE = 2;
  699. private static final int SCIENTIFICSTYLE = 3;
  700. private static final int INTEGERSTYLE = 4;
  701. /**
  702. * True if the the grouping (i.e. thousands) separator is used when
  703. * formatting and parsing numbers.
  704. *
  705. * @serial
  706. * @see #isGroupingUsed
  707. */
  708. private boolean groupingUsed = true;
  709. /**
  710. * The maximum number of digits allowed in the integer portion of a
  711. * number. <code>maxIntegerDigits</code> must be greater than or equal to
  712. * <code>minIntegerDigits</code>.
  713. * <p>
  714. * <strong>Note:</strong> This field exists only for serialization
  715. * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
  716. * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
  717. * When writing to a stream, <code>maxIntegerDigits</code> is set to
  718. * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
  719. * whichever is smaller. When reading from a stream, this field is used
  720. * only if <code>serialVersionOnStream</code> is less than 1.
  721. *
  722. * @serial
  723. * @see #getMaximumIntegerDigits
  724. */
  725. private byte maxIntegerDigits = 40;
  726. /**
  727. * The minimum number of digits allowed in the integer portion of a
  728. * number. <code>minimumIntegerDigits</code> must be less than or equal to
  729. * <code>maximumIntegerDigits</code>.
  730. * <p>
  731. * <strong>Note:</strong> This field exists only for serialization
  732. * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
  733. * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
  734. * When writing to a stream, <code>minIntegerDigits</code> is set to
  735. * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
  736. * whichever is smaller. When reading from a stream, this field is used
  737. * only if <code>serialVersionOnStream</code> is less than 1.
  738. *
  739. * @serial
  740. * @see #getMinimumIntegerDigits
  741. */
  742. private byte minIntegerDigits = 1;
  743. /**
  744. * The maximum number of digits allowed in the fractional portion of a
  745. * number. <code>maximumFractionDigits</code> must be greater than or equal to
  746. * <code>minimumFractionDigits</code>.
  747. * <p>
  748. * <strong>Note:</strong> This field exists only for serialization
  749. * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
  750. * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
  751. * When writing to a stream, <code>maxFractionDigits</code> is set to
  752. * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
  753. * whichever is smaller. When reading from a stream, this field is used
  754. * only if <code>serialVersionOnStream</code> is less than 1.
  755. *
  756. * @serial
  757. * @see #getMaximumFractionDigits
  758. */
  759. private byte maxFractionDigits = 3; // invariant, >= minFractionDigits
  760. /**
  761. * The minimum number of digits allowed in the fractional portion of a
  762. * number. <code>minimumFractionDigits</code> must be less than or equal to
  763. * <code>maximumFractionDigits</code>.
  764. * <p>
  765. * <strong>Note:</strong> This field exists only for serialization
  766. * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
  767. * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
  768. * When writing to a stream, <code>minFractionDigits</code> is set to
  769. * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
  770. * whichever is smaller. When reading from a stream, this field is used
  771. * only if <code>serialVersionOnStream</code> is less than 1.
  772. *
  773. * @serial
  774. * @see #getMinimumFractionDigits
  775. */
  776. private byte minFractionDigits = 0;
  777. /**
  778. * True if this format will parse numbers as integers only.
  779. *
  780. * @serial
  781. * @see #isParseIntegerOnly
  782. */
  783. private boolean parseIntegerOnly = false;
  784. // new fields for 1.2. byte is too small for integer digits.
  785. /**
  786. * The maximum number of digits allowed in the integer portion of a
  787. * number. <code>maximumIntegerDigits</code> must be greater than or equal to
  788. * <code>minimumIntegerDigits</code>.
  789. *
  790. * @serial
  791. * @since 1.2
  792. * @see #getMaximumIntegerDigits
  793. */
  794. private int maximumIntegerDigits = 40;
  795. /**
  796. * The minimum number of digits allowed in the integer portion of a
  797. * number. <code>minimumIntegerDigits</code> must be less than or equal to
  798. * <code>maximumIntegerDigits</code>.
  799. *
  800. * @serial
  801. * @since 1.2
  802. * @see #getMinimumIntegerDigits
  803. */
  804. private int minimumIntegerDigits = 1;
  805. /**
  806. * The maximum number of digits allowed in the fractional portion of a
  807. * number. <code>maximumFractionDigits</code> must be greater than or equal to
  808. * <code>minimumFractionDigits</code>.
  809. *
  810. * @serial
  811. * @since 1.2
  812. * @see #getMaximumFractionDigits
  813. */
  814. private int maximumFractionDigits = 3; // invariant, >= minFractionDigits
  815. /**
  816. * The minimum number of digits allowed in the fractional portion of a
  817. * number. <code>minimumFractionDigits</code> must be less than or equal to
  818. * <code>maximumFractionDigits</code>.
  819. *
  820. * @serial
  821. * @since 1.2
  822. * @see #getMinimumFractionDigits
  823. */
  824. private int minimumFractionDigits = 0;
  825. static final int currentSerialVersion = 1;
  826. /**
  827. * Describes the version of <code>NumberFormat</code> present on the stream.
  828. * Possible values are:
  829. * <ul>
  830. * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
  831. * In this version, the <code>int</code> fields such as
  832. * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
  833. * fields such as <code>maxIntegerDigits</code> are used instead.
  834. *
  835. * <li><b>1</b>: the 1.2 version of the stream format. The values of the
  836. * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
  837. * and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  838. * are used instead.
  839. * </ul>
  840. * When streaming out a <code>NumberFormat</code>, the most recent format
  841. * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
  842. * is always written.
  843. *
  844. * @serial
  845. * @since 1.2
  846. */
  847. private int serialVersionOnStream = currentSerialVersion;
  848. // Removed "implements Cloneable" clause. Needs to update serialization
  849. // ID for backward compatibility.
  850. static final long serialVersionUID = -2308460125733713944L;
  851. //
  852. // class for AttributedCharacterIterator attributes
  853. //
  854. /**
  855. * Defines constants that are used as attribute keys in the
  856. * <code>AttributedCharacterIterator</code> returned
  857. * from <code>NumberFormat.formatToCharacterIterator</code> and as
  858. * field identifiers in <code>FieldPosition</code>.
  859. *
  860. * @since 1.4
  861. */
  862. public static class Field extends Format.Field {
  863. // table of all instances in this class, used by readResolve
  864. private static final Map instanceMap = new HashMap(11);
  865. /**
  866. * Creates a Field instance with the specified
  867. * name.
  868. *
  869. * @param name Name of the attribute
  870. */
  871. protected Field(String name) {
  872. super(name);
  873. if (this.getClass() == NumberFormat.Field.class) {
  874. instanceMap.put(name, this);
  875. }
  876. }
  877. /**
  878. * Resolves instances being deserialized to the predefined constants.
  879. *
  880. * @throws InvalidObjectException if the constant could not be
  881. * resolved.
  882. * @return resolved NumberFormat.Field constant
  883. */
  884. protected Object readResolve() throws InvalidObjectException {
  885. if (this.getClass() != NumberFormat.Field.class) {
  886. throw new InvalidObjectException("subclass didn't correctly implement readResolve");
  887. }
  888. Object instance = instanceMap.get(getName());
  889. if (instance != null) {
  890. return instance;
  891. } else {
  892. throw new InvalidObjectException("unknown attribute name");
  893. }
  894. }
  895. /**
  896. * Constant identifying the integer field.
  897. */
  898. public static final Field INTEGER = new Field("integer");
  899. /**
  900. * Constant identifying the fraction field.
  901. */
  902. public static final Field FRACTION = new Field("fraction");
  903. /**
  904. * Constant identifying the exponent field.
  905. */
  906. public static final Field EXPONENT = new Field("exponent");
  907. /**
  908. * Constant identifying the decimal separator field.
  909. */
  910. public static final Field DECIMAL_SEPARATOR =
  911. new Field("decimal separator");
  912. /**
  913. * Constant identifying the sign field.
  914. */
  915. public static final Field SIGN = new Field("sign");
  916. /**
  917. * Constant identifying the grouping separator field.
  918. */
  919. public static final Field GROUPING_SEPARATOR =
  920. new Field("grouping separator");
  921. /**
  922. * Constant identifying the exponent symbol field.
  923. */
  924. public static final Field EXPONENT_SYMBOL = new
  925. Field("exponent symbol");
  926. /**
  927. * Constant identifying the percent field.
  928. */
  929. public static final Field PERCENT = new Field("percent");
  930. /**
  931. * Constant identifying the permille field.
  932. */
  933. public static final Field PERMILLE = new Field("per mille");
  934. /**
  935. * Constant identifying the currency field.
  936. */
  937. public static final Field CURRENCY = new Field("currency");
  938. /**
  939. * Constant identifying the exponent sign field.
  940. */
  941. public static final Field EXPONENT_SIGN = new Field("exponent sign");
  942. }
  943. }