1. /*
  2. * @(#)NumberFormat.java 1.47 00/01/19
  3. *
  4. * Copyright 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. /*
  11. * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
  12. * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
  13. *
  14. * The original version of this source code and documentation is copyrighted
  15. * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  16. * materials are provided under terms of a License Agreement between Taligent
  17. * and Sun. This technology is protected by multiple US and International
  18. * patents. This notice and attribution to Taligent may not be removed.
  19. * Taligent is a registered trademark of Taligent, Inc.
  20. *
  21. */
  22. package java.text;
  23. import java.util.Locale;
  24. import java.util.ResourceBundle;
  25. import java.text.resources.*;
  26. import java.util.Hashtable;
  27. import java.math.BigInteger;
  28. import java.io.IOException;
  29. import java.io.InvalidObjectException;
  30. import java.io.ObjectInputStream;
  31. import java.io.ObjectOutputStream;
  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>getCurrencyInstance</code> to get the
  79. * currency number format. And use <code>getPercentInstance</code> to get a
  80. * format for displaying percentages. With this format, a fraction like
  81. * 0.53 is displayed as 53%.
  82. *
  83. * <p>
  84. * You can also control the display of numbers with such methods as
  85. * <code>setMinimumFractionDigits</code>.
  86. * If you want even more control over the format or parsing,
  87. * or want to give your users more control,
  88. * you can try casting the <code>NumberFormat</code> you get from the factory methods
  89. * to a <code>DecimalNumberFormat</code>. This will work for the vast majority
  90. * of locales; just remember to put it in a <code>try</code> block in case you
  91. * encounter an unusual one.
  92. *
  93. * <p>
  94. * NumberFormat and DecimalFormat are designed such that some controls
  95. * work for formatting and others work for parsing. The following is
  96. * the detailed description for each these control methods,
  97. * <p>
  98. * setParseIntegerOnly : only affects parsing, e.g.
  99. * if true, "3456.78" -> 3456 (and leaves the parse position just after index 6)
  100. * if false, "3456.78" -> 3456.78 (and leaves the parse position just after index 8)
  101. * This is independent of formatting. If you want to not show a decimal point
  102. * where there might be no digits after the decimal point, use
  103. * setDecimalSeparatorAlwaysShown.
  104. * <p>
  105. * setDecimalSeparatorAlwaysShown : only affects formatting, and only where
  106. * there might be no digits after the decimal point, such as with a pattern
  107. * like "#,##0.##", e.g.,
  108. * if true, 3456.00 -> "3,456."
  109. * if false, 3456.00 -> "3456"
  110. * This is independent of parsing. If you want parsing to stop at the decimal
  111. * point, use setParseIntegerOnly.
  112. *
  113. * <p>
  114. * You can also use forms of the <code>parse</code> and <code>format</code>
  115. * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
  116. * allow you to:
  117. * <ul>
  118. * <li> progressively parse through pieces of a string
  119. * <li> align the decimal point and other areas
  120. * </ul>
  121. * For example, you can align numbers in two ways:
  122. * <ol>
  123. * <li> If you are using a monospaced font with spacing for alignment,
  124. * you can pass the <code>FieldPosition</code> in your format call, with
  125. * <code>field</code> = <code>INTEGER_FIELD</code>. On output,
  126. * <code>getEndIndex</code> will be set to the offset between the
  127. * last character of the integer and the decimal. Add
  128. * (desiredSpaceCount - getEndIndex) spaces at the front of the string.
  129. *
  130. * <li> If you are using proportional fonts,
  131. * instead of padding with spaces, measure the width
  132. * of the string in pixels from the start to <code>getEndIndex</code>.
  133. * Then move the pen by
  134. * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
  135. * It also works where there is no decimal, but possibly additional
  136. * characters at the end, e.g., with parentheses in negative
  137. * numbers: "(12)" for -12.
  138. * </ol>
  139. *
  140. * @see DecimalFormat
  141. * @see ChoiceFormat
  142. * @version 1.47, 01/19/00
  143. * @author Mark Davis
  144. * @author Helena Shih
  145. */
  146. public abstract class NumberFormat extends Format{
  147. /**
  148. * Field constant used to construct a FieldPosition object. Signifies that
  149. * the position of the integer part of a formatted number should be returned.
  150. * @see java.text.FieldPosition
  151. */
  152. public static final int INTEGER_FIELD = 0;
  153. /**
  154. * Field constant used to construct a FieldPosition object. Signifies that
  155. * the position of the fraction part of a formatted number should be returned.
  156. * @see java.text.FieldPosition
  157. */
  158. public static final int FRACTION_FIELD = 1;
  159. /**
  160. * Formats an object to produce a string.
  161. * This general routines allows polymorphic parsing and
  162. * formatting for objectst.
  163. * @param obj The object to format
  164. * @param toAppendTo where the text is to be appended
  165. * @param pos On input: an alignment field, if desired.
  166. * On output: the offsets of the alignment field.
  167. * @return the value passed in as toAppendTo (this allows chaining,
  168. * as with StringBuffer.append())
  169. * @exception IllegalArgumentException when the Format cannot format the
  170. * given object.
  171. * @see java.text.FieldPosition
  172. */
  173. public final StringBuffer format(Object number,
  174. StringBuffer toAppendTo,
  175. FieldPosition pos)
  176. {
  177. if (number instanceof Long ||
  178. (number instanceof BigInteger && ((BigInteger)number).bitLength() < 64)) {
  179. return format(((Number)number).longValue(), toAppendTo, pos);
  180. }
  181. /* Here is the code that's required to get all the bits we can out of
  182. * BigDecimal into a long or double. In the interests of simplicity, we
  183. * don't use this code; we just convert BigDecimal values into doubles.
  184. * (Actually, to really do things right, you'd compare against both
  185. * Long.MIN_VALUE and Long.MAX_VALUE, since they differ in magnitude.)
  186. * Liu 6/98
  187. */
  188. // else if (number instanceof BigDecimal) {
  189. // BigDecimal bd = (BigDecimal)number;
  190. // try {
  191. // if (bd.setScale(0, BigDecimal.ROUND_UNNECESSARY).
  192. // abs().compareTo(new BigDecimal("9223372036854775807")) <= 0) {
  193. // return format(((Number)number).longValue(), toAppendTo, pos);
  194. // }
  195. // }
  196. // catch (ArithmeticException e) {}
  197. // return format(((Number)number).doubleValue(), toAppendTo, pos);
  198. // }
  199. else if (number instanceof Number) {
  200. return format(((Number)number).doubleValue(), toAppendTo, pos);
  201. }
  202. else {
  203. throw new IllegalArgumentException("Cannot format given Object as a Number");
  204. }
  205. }
  206. /**
  207. * Parses a string to produce an object.
  208. * @param source the string to parse.
  209. * @param parsePosition Input-Output parameter. On input, the position
  210. * to begin parsing. On output, the position of the first unparse character.
  211. * @return Object parsed from string. In case of error, returns null.
  212. * @see java.text.ParsePosition
  213. */
  214. public final Object parseObject(String source,
  215. ParsePosition parsePosition)
  216. {
  217. return parse(source, parsePosition);
  218. }
  219. /**
  220. * Specialization of format.
  221. * @see java.text.Format#format
  222. */
  223. public final String format (double number) {
  224. return format(number,new StringBuffer(),
  225. new FieldPosition(0)).toString();
  226. }
  227. /**
  228. * Specialization of format.
  229. * @see java.text.Format#format
  230. */
  231. public final String format (long number) {
  232. return format(number,new StringBuffer(),
  233. new FieldPosition(0)).toString();
  234. }
  235. /**
  236. * Specialization of format.
  237. * @see java.text.Format#format
  238. */
  239. public abstract StringBuffer format(double number,
  240. StringBuffer toAppendTo,
  241. FieldPosition pos);
  242. /**
  243. * Specialization of format.
  244. * @see java.text.Format#format
  245. */
  246. public abstract StringBuffer format(long number,
  247. StringBuffer toAppendTo,
  248. FieldPosition pos);
  249. /**
  250. * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
  251. * Long.MAX_VALUE] and with no decimals), otherwise a Double.
  252. * If IntegerOnly is set, will stop at a decimal
  253. * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
  254. * after the 1).
  255. * Does not throw an exception; if no object can be parsed, index is
  256. * unchanged!
  257. * @see java.text.NumberFormat#isParseIntegerOnly
  258. * @see java.text.Format#parseObject
  259. */
  260. public abstract Number parse(String text, ParsePosition parsePosition);
  261. /**
  262. * Convenience method.
  263. *
  264. * @exception ParseException if the specified string is invalid.
  265. * @see #format
  266. */
  267. public Number parse(String text) throws ParseException {
  268. ParsePosition parsePosition = new ParsePosition(0);
  269. Number result = parse(text, parsePosition);
  270. if (parsePosition.index == 0) {
  271. throw new ParseException("Unparseable number: \"" + text + "\"",
  272. parsePosition.errorIndex);
  273. }
  274. return result;
  275. }
  276. /**
  277. * Returns true if this format will parse numbers as integers only.
  278. * For example in the English locale, with ParseIntegerOnly true, the
  279. * string "1234." would be parsed as the integer value 1234 and parsing
  280. * would stop at the "." character. Of course, the exact format accepted
  281. * by the parse operation is locale dependant and determined by sub-classes
  282. * of NumberFormat.
  283. */
  284. public boolean isParseIntegerOnly() {
  285. return parseIntegerOnly;
  286. }
  287. /**
  288. * Sets whether or not numbers should be parsed as integers only.
  289. * @see #isParseIntegerOnly
  290. */
  291. public void setParseIntegerOnly(boolean value) {
  292. parseIntegerOnly = value;
  293. }
  294. //============== Locale Stuff =====================
  295. /**
  296. * Returns the default number format for the current default locale.
  297. * The default format is one of the styles provided by the other
  298. * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
  299. * Exactly which one is locale dependant.
  300. */
  301. public final static NumberFormat getInstance() {
  302. return getInstance(Locale.getDefault(), NUMBERSTYLE);
  303. }
  304. /**
  305. * Returns the default number format for the specified locale.
  306. * The default format is one of the styles provided by the other
  307. * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
  308. * Exactly which one is locale dependant.
  309. */
  310. public static NumberFormat getInstance(Locale inLocale) {
  311. return getInstance(inLocale, NUMBERSTYLE);
  312. }
  313. /**
  314. * Returns a general-purpose number format for the current default locale.
  315. */
  316. public final static NumberFormat getNumberInstance() {
  317. return getInstance(Locale.getDefault(), NUMBERSTYLE);
  318. }
  319. /**
  320. * Returns a general-purpose number format for the specified locale.
  321. */
  322. public static NumberFormat getNumberInstance(Locale inLocale) {
  323. return getInstance(inLocale, NUMBERSTYLE);
  324. }
  325. /**
  326. * Returns a currency format for the current default locale.
  327. */
  328. public final static NumberFormat getCurrencyInstance() {
  329. return getInstance(Locale.getDefault(), CURRENCYSTYLE);
  330. }
  331. /**
  332. * Returns a currency format for the specified locale.
  333. */
  334. public static NumberFormat getCurrencyInstance(Locale inLocale) {
  335. return getInstance(inLocale, CURRENCYSTYLE);
  336. }
  337. /**
  338. * Returns a percentage format for the current default locale.
  339. */
  340. public final static NumberFormat getPercentInstance() {
  341. return getInstance(Locale.getDefault(), PERCENTSTYLE);
  342. }
  343. /**
  344. * Returns a percentage format for the specified locale.
  345. */
  346. public static NumberFormat getPercentInstance(Locale inLocale) {
  347. return getInstance(inLocale, PERCENTSTYLE);
  348. }
  349. /**
  350. * Returns a scientific format for the current default locale.
  351. */
  352. /*public*/ final static NumberFormat getScientificInstance() {
  353. return getInstance(Locale.getDefault(), SCIENTIFICSTYLE);
  354. }
  355. /**
  356. * Returns a scientific format for the specified locale.
  357. */
  358. /*public*/ static NumberFormat getScientificInstance(Locale inLocale) {
  359. return getInstance(inLocale, SCIENTIFICSTYLE);
  360. }
  361. /**
  362. * Get the set of Locales for which NumberFormats are installed
  363. * @return available locales
  364. */
  365. public static Locale[] getAvailableLocales() {
  366. return LocaleData.getAvailableLocales("NumberPatterns");
  367. }
  368. /**
  369. * Overrides hashCode
  370. */
  371. public int hashCode() {
  372. return maximumIntegerDigits * 37 + maxFractionDigits;
  373. // just enough fields for a reasonable distribution
  374. }
  375. /**
  376. * Overrides equals
  377. */
  378. public boolean equals(Object obj) {
  379. if (obj == null) return false;
  380. if (this == obj)
  381. return true;
  382. if (getClass() != obj.getClass())
  383. return false;
  384. NumberFormat other = (NumberFormat) obj;
  385. return (maximumIntegerDigits == other.maximumIntegerDigits
  386. && minimumIntegerDigits == other.minimumIntegerDigits
  387. && maximumFractionDigits == other.maximumFractionDigits
  388. && minimumFractionDigits == other.minimumFractionDigits
  389. && groupingUsed == other.groupingUsed
  390. && parseIntegerOnly == other.parseIntegerOnly);
  391. }
  392. /**
  393. * Overrides Cloneable
  394. */
  395. public Object clone()
  396. {
  397. NumberFormat other = (NumberFormat) super.clone();
  398. return other;
  399. }
  400. /**
  401. * Returns true if grouping is used in this format. For example, in the
  402. * English locale, with grouping on, the number 1234567 might be formatted
  403. * as "1,234,567". The grouping separator as well as the size of each group
  404. * is locale dependant and is determined by sub-classes of NumberFormat.
  405. * @see #setGroupingUsed
  406. */
  407. public boolean isGroupingUsed() {
  408. return groupingUsed;
  409. }
  410. /**
  411. * Set whether or not grouping will be used in this format.
  412. * @see #isGroupingUsed
  413. */
  414. public void setGroupingUsed(boolean newValue) {
  415. groupingUsed = newValue;
  416. }
  417. /**
  418. * Returns the maximum number of digits allowed in the integer portion of a
  419. * number.
  420. * @see #setMaximumIntegerDigits
  421. */
  422. public int getMaximumIntegerDigits() {
  423. return maximumIntegerDigits;
  424. }
  425. /**
  426. * Sets the maximum number of digits allowed in the integer portion of a
  427. * number. maximumIntegerDigits must be >= minimumIntegerDigits. If the
  428. * new value for maximumIntegerDigits is less than the current value
  429. * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
  430. * the new value.
  431. * @param newValue the maximum number of integer digits to be shown; if
  432. * less than zero, then zero is used. The concrete subclass may enforce an
  433. * upper limit to this value appropriate to the numeric type being formatted.
  434. * @see #getMaximumIntegerDigits
  435. */
  436. public void setMaximumIntegerDigits(int newValue) {
  437. maximumIntegerDigits = Math.max(0,newValue);
  438. if (minimumIntegerDigits > maximumIntegerDigits)
  439. minimumIntegerDigits = maximumIntegerDigits;
  440. }
  441. /**
  442. * Returns the minimum number of digits allowed in the integer portion of a
  443. * number.
  444. * @see #setMinimumIntegerDigits
  445. */
  446. public int getMinimumIntegerDigits() {
  447. return minimumIntegerDigits;
  448. }
  449. /**
  450. * Sets the minimum number of digits allowed in the integer portion of a
  451. * number. minimumIntegerDigits must be <= maximumIntegerDigits. If the
  452. * new value for minimumIntegerDigits exceeds the current value
  453. * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
  454. * the new value
  455. * @param newValue the minimum number of integer digits to be shown; if
  456. * less than zero, then zero is used. The concrete subclass may enforce an
  457. * upper limit to this value appropriate to the numeric type being formatted.
  458. * @see #getMinimumIntegerDigits
  459. */
  460. public void setMinimumIntegerDigits(int newValue) {
  461. minimumIntegerDigits = Math.max(0,newValue);
  462. if (minimumIntegerDigits > maximumIntegerDigits)
  463. maximumIntegerDigits = minimumIntegerDigits;
  464. }
  465. /**
  466. * Returns the maximum number of digits allowed in the fraction portion of a
  467. * number.
  468. * @see #setMaximumFractionDigits
  469. */
  470. public int getMaximumFractionDigits() {
  471. return maximumFractionDigits;
  472. }
  473. /**
  474. * Sets the maximum number of digits allowed in the fraction portion of a
  475. * number. maximumFractionDigits must be >= minimumFractionDigits. If the
  476. * new value for maximumFractionDigits is less than the current value
  477. * of minimumFractionDigits, then minimumFractionDigits will also be set to
  478. * the new value.
  479. * @param newValue the maximum number of fraction digits to be shown; if
  480. * less than zero, then zero is used. The concrete subclass may enforce an
  481. * upper limit to this value appropriate to the numeric type being formatted.
  482. * @see #getMaximumFractionDigits
  483. */
  484. public void setMaximumFractionDigits(int newValue) {
  485. maximumFractionDigits = Math.max(0,newValue);
  486. if (maximumFractionDigits < minimumFractionDigits)
  487. minimumFractionDigits = maximumFractionDigits;
  488. }
  489. /**
  490. * Returns the minimum number of digits allowed in the fraction portion of a
  491. * number.
  492. * @see #setMinimumFractionDigits
  493. */
  494. public int getMinimumFractionDigits() {
  495. return minimumFractionDigits;
  496. }
  497. /**
  498. * Sets the minimum number of digits allowed in the fraction portion of a
  499. * number. minimumFractionDigits must be <= maximumFractionDigits. If the
  500. * new value for minimumFractionDigits exceeds the current value
  501. * of maximumFractionDigits, then maximumIntegerDigits will also be set to
  502. * the new value
  503. * @param newValue the minimum number of fraction digits to be shown; if
  504. * less than zero, then zero is used. The concrete subclass may enforce an
  505. * upper limit to this value appropriate to the numeric type being formatted.
  506. * @see #getMinimumFractionDigits
  507. */
  508. public void setMinimumFractionDigits(int newValue) {
  509. minimumFractionDigits = Math.max(0,newValue);
  510. if (maximumFractionDigits < minimumFractionDigits)
  511. maximumFractionDigits = minimumFractionDigits;
  512. }
  513. // =======================privates===============================
  514. private static NumberFormat getInstance(Locale desiredLocale,
  515. int choice)
  516. {
  517. /* try the cache first */
  518. String[] numberPatterns = (String[])cachedLocaleData.get(desiredLocale);
  519. if (numberPatterns == null) { /* cache miss */
  520. ResourceBundle resource = ResourceBundle.getBundle
  521. ("java.text.resources.LocaleElements", desiredLocale);
  522. numberPatterns = resource.getStringArray("NumberPatterns");
  523. /* update cache */
  524. cachedLocaleData.put(desiredLocale, numberPatterns);
  525. }
  526. return new DecimalFormat(numberPatterns[choice],
  527. new DecimalFormatSymbols(desiredLocale));
  528. }
  529. /**
  530. * First, read in the default serializable data.
  531. *
  532. * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
  533. * the stream was written by JDK 1.1,
  534. * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  535. * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
  536. * since the <code>int</code> fields were not present in JDK 1.1.
  537. * Finally, set serialVersionOnStream back to the maximum allowed value so that
  538. * default serialization will work properly if this object is streamed out again.
  539. *
  540. * <p>If <code>minimumIntegerDigits</code> is greater than
  541. * <code>maximumIntegerDigits</code> or <code>minimumFractionDigits</code>
  542. * is greater than <code>maximumFractionDigits</code>, then the stream data
  543. * is invalid and this method throws an <code>InvalidObjectException</code>.
  544. * In addition, if any of these values is negative, then this method throws
  545. * an <code>InvalidObjectException</code>.
  546. *
  547. * @since 1.2
  548. */
  549. private void readObject(ObjectInputStream stream)
  550. throws IOException, ClassNotFoundException
  551. {
  552. stream.defaultReadObject();
  553. if (serialVersionOnStream < 1) {
  554. // Didn't have additional int fields, reassign to use them.
  555. maximumIntegerDigits = maxIntegerDigits;
  556. minimumIntegerDigits = minIntegerDigits;
  557. maximumFractionDigits = maxFractionDigits;
  558. minimumFractionDigits = minFractionDigits;
  559. }
  560. if (minimumIntegerDigits > maximumIntegerDigits ||
  561. minimumFractionDigits > maximumFractionDigits ||
  562. minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
  563. throw new InvalidObjectException("Digit count range invalid");
  564. }
  565. serialVersionOnStream = currentSerialVersion;
  566. }
  567. /**
  568. * Write out the default serializable data, after first setting
  569. * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
  570. * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  571. * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
  572. * with the JDK 1.1 version of the stream format.
  573. *
  574. * @since 1.2
  575. */
  576. private void writeObject(ObjectOutputStream stream)
  577. throws IOException
  578. {
  579. maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  580. (byte)maximumIntegerDigits;
  581. minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  582. (byte)minimumIntegerDigits;
  583. maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  584. (byte)maximumFractionDigits;
  585. minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  586. (byte)minimumFractionDigits;
  587. stream.defaultWriteObject();
  588. }
  589. /**
  590. * Cache to hold the NumberPatterns of a Locale.
  591. */
  592. private static final Hashtable cachedLocaleData = new Hashtable(3);
  593. // Constants used by factory methods to specify a style of format.
  594. private static final int NUMBERSTYLE = 0;
  595. private static final int CURRENCYSTYLE = 1;
  596. private static final int PERCENTSTYLE = 2;
  597. private static final int SCIENTIFICSTYLE = 3;
  598. /**
  599. * True if the the grouping (i.e. thousands) separator is used when
  600. * formatting and parsing numbers.
  601. *
  602. * @serial
  603. * @see #isGroupingUsed
  604. */
  605. private boolean groupingUsed = true;
  606. /**
  607. * The maximum number of digits allowed in the integer portion of a
  608. * number. <code>maxIntegerDigits</code> must be greater than or equal to
  609. * <code>minIntegerDigits</code>.
  610. * <p>
  611. * <strong>Note:</strong> This field exists only for serialization
  612. * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
  613. * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
  614. * When writing to a stream, <code>maxIntegerDigits</code> is set to
  615. * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
  616. * whichever is smaller. When reading from a stream, this field is used
  617. * only if <code>serialVersionOnStream</code> is less than 1.
  618. *
  619. * @serial
  620. * @see #getMaximumIntegerDigits
  621. */
  622. private byte maxIntegerDigits = 40;
  623. /**
  624. * The minimum number of digits allowed in the integer portion of a
  625. * number. <code>minimumIntegerDigits</code> must be less than or equal to
  626. * <code>maximumIntegerDigits</code>.
  627. * <p>
  628. * <strong>Note:</strong> This field exists only for serialization
  629. * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
  630. * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
  631. * When writing to a stream, <code>minIntegerDigits</code> is set to
  632. * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
  633. * whichever is smaller. When reading from a stream, this field is used
  634. * only if <code>serialVersionOnStream</code> is less than 1.
  635. *
  636. * @serial
  637. * @see #getMinimumIntegerDigits
  638. */
  639. private byte minIntegerDigits = 1;
  640. /**
  641. * The maximum number of digits allowed in the fractional portion of a
  642. * number. <code>maximumFractionDigits</code> must be greater than or equal to
  643. * <code>minimumFractionDigits</code>.
  644. * <p>
  645. * <strong>Note:</strong> This field exists only for serialization
  646. * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
  647. * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
  648. * When writing to a stream, <code>maxFractionDigits</code> is set to
  649. * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
  650. * whichever is smaller. When reading from a stream, this field is used
  651. * only if <code>serialVersionOnStream</code> is less than 1.
  652. *
  653. * @serial
  654. * @see #getMaximumFractionDigits
  655. */
  656. private byte maxFractionDigits = 3; // invariant, >= minFractionDigits
  657. /**
  658. * The minimum number of digits allowed in the fractional portion of a
  659. * number. <code>minimumFractionDigits</code> must be less than or equal to
  660. * <code>maximumFractionDigits</code>.
  661. * <p>
  662. * <strong>Note:</strong> This field exists only for serialization
  663. * compatibility with JDK 1.1. In Java platform 2 v1.2 and higher, the new
  664. * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
  665. * When writing to a stream, <code>minFractionDigits</code> is set to
  666. * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
  667. * whichever is smaller. When reading from a stream, this field is used
  668. * only if <code>serialVersionOnStream</code> is less than 1.
  669. *
  670. * @serial
  671. * @see #getMinimumFractionDigits
  672. */
  673. private byte minFractionDigits = 0;
  674. /**
  675. * True if this format will parse numbers as integers only.
  676. *
  677. * @serial
  678. * @see #isParseIntegerOnly
  679. */
  680. private boolean parseIntegerOnly = false;
  681. // new fields for 1.2. byte is too small for integer digits.
  682. /**
  683. * The maximum number of digits allowed in the integer portion of a
  684. * number. <code>maximumIntegerDigits</code> must be greater than or equal to
  685. * <code>minimumIntegerDigits</code>.
  686. *
  687. * @serial
  688. * @since 1.2
  689. * @see #getMaximumIntegerDigits
  690. */
  691. private int maximumIntegerDigits = 40;
  692. /**
  693. * The minimum number of digits allowed in the integer portion of a
  694. * number. <code>minimumIntegerDigits</code> must be less than or equal to
  695. * <code>maximumIntegerDigits</code>.
  696. *
  697. * @serial
  698. * @since 1.2
  699. * @see #getMinimumIntegerDigits
  700. */
  701. private int minimumIntegerDigits = 1;
  702. /**
  703. * The maximum number of digits allowed in the fractional portion of a
  704. * number. <code>maximumFractionDigits</code> must be greater than or equal to
  705. * <code>minimumFractionDigits</code>.
  706. *
  707. * @serial
  708. * @since 1.2
  709. * @see #getMaximumFractionDigits
  710. */
  711. private int maximumFractionDigits = 3; // invariant, >= minFractionDigits
  712. /**
  713. * The minimum number of digits allowed in the fractional portion of a
  714. * number. <code>minimumFractionDigits</code> must be less than or equal to
  715. * <code>maximumFractionDigits</code>.
  716. *
  717. * @serial
  718. * @since 1.2
  719. * @see #getMinimumFractionDigits
  720. */
  721. private int minimumFractionDigits = 0;
  722. static final int currentSerialVersion = 1;
  723. /**
  724. * Describes the version of <code>NumberFormat</code> present on the stream.
  725. * Possible values are:
  726. * <ul>
  727. * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
  728. * In this version, the <code>int</code> fields such as
  729. * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
  730. * fields such as <code>maxIntegerDigits</code> are used instead.
  731. *
  732. * <li><b>1</b>: the 1.2 version of the stream format. The values of the
  733. * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
  734. * and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  735. * are used instead.
  736. * </ul>
  737. * When streaming out a <code>NumberFormat</code>, the most recent format
  738. * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
  739. * is always written.
  740. *
  741. * @serial
  742. * @since 1.2
  743. */
  744. private int serialVersionOnStream = currentSerialVersion;
  745. // Removed "implements Cloneable" clause. Needs to update serialization
  746. // ID for backward compatibility.
  747. static final long serialVersionUID = -2308460125733713944L;
  748. }