src/share/classes/java/util/Formatter.java

Print this page

        

@@ -48,10 +48,12 @@
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
 
 import sun.misc.FpUtils;
 import sun.misc.DoubleConsts;
 import sun.misc.FormattedFloatingDecimal;
 

@@ -1836,26 +1838,55 @@
  * @author  Iris Clark
  * @since 1.5
  */
 public final class Formatter implements Closeable, Flushable {
     private Appendable a;
-    private Locale l;
+    private final Locale l;
 
     private IOException lastException;
 
-    private char zero = '0';
+    private final char zero;
     private static double scaleUp;
 
     // 1 (sign) + 19 (max # sig digits) + 1 ('.') + 1 ('e') + 1 (sign)
     // + 3 (max # exp digits) + 4 (error) = 30
     private static final int MAX_FD_CHARS = 30;
 
-    // Initialize internal data.
-    private void init(Appendable a, Locale l) {
+    /**
+     * Verifies that the given charset is supported.
+     * @throws NullPointerException          is csn is null
+     * @throws UnsupportedEncodingException  if the charset is not supported
+     */
+    private static Void verifyCharsetName(String csn)
+            throws UnsupportedEncodingException {
+        Objects.nonNull(csn, "charsetName");
+        try {
+            if (Charset.isSupported(csn))
+                return null;
+        } catch (IllegalCharsetNameException unused) {
+            /* swallow this exception since UnsupportedEncodingException
+             * will be thrown */
+        }
+        throw new UnsupportedEncodingException(csn);
+    }
+
+    private static final Appendable nonNullAppendable(Appendable a) {
+        if (a == null)
+            return new StringBuilder();
+
+        return a;
+    }
+
+    // Private constructors
+    private Formatter(Void unused, Locale l, Appendable a) {
+        this(l, a);
+    }
+
+    private Formatter(Locale l, Appendable a) {
         this.a = a;
         this.l = l;
-        setZero();
+        this.zero = getZero(l);
     }
 
     /**
      * Constructs a new formatter.
      *

@@ -1865,11 +1896,11 @@
      * #toString toString()}.  The locale used is the {@linkplain
      * Locale#getDefault() default locale} for this instance of the Java
      * virtual machine.
      */
     public Formatter() {
-        init(new StringBuilder(), Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT), new StringBuilder());
     }
 
     /**
      * Constructs a new formatter with the specified destination.
      *

@@ -1879,13 +1910,11 @@
      * @param  a
      *         Destination for the formatted output.  If {@code a} is
      *         {@code null} then a {@link StringBuilder} will be created.
      */
     public Formatter(Appendable a) {
-        if (a == null)
-            a = new StringBuilder();
-        init(a, Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT), nonNullAppendable(a));
     }
 
     /**
      * Constructs a new formatter with the specified locale.
      *

@@ -1898,11 +1927,11 @@
      *         The {@linkplain java.util.Locale locale} to apply during
      *         formatting.  If {@code l} is {@code null} then no localization
      *         is applied.
      */
     public Formatter(Locale l) {
-        init(new StringBuilder(), l);
+        this(l, new StringBuilder());
     }
 
     /**
      * Constructs a new formatter with the specified destination and locale.
      *

@@ -1914,13 +1943,11 @@
      *         The {@linkplain java.util.Locale locale} to apply during
      *         formatting.  If {@code l} is {@code null} then no localization
      *         is applied.
      */
     public Formatter(Appendable a, Locale l) {
-        if (a == null)
-            a = new StringBuilder();
-        init(a, l);
+        this(l, nonNullAppendable(a));
     }
 
     /**
      * Constructs a new formatter with the specified file name.
      *

@@ -1947,12 +1974,12 @@
      *          regular file and a new regular file of that name cannot be
      *          created, or if some other error occurs while opening or
      *          creating the file
      */
     public Formatter(String fileName) throws FileNotFoundException {
-        init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
-             Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT),
+             new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))));
     }
 
     /**
      * Constructs a new formatter with the specified file name and charset.
      *

@@ -2023,12 +2050,13 @@
      *          If the named charset is not supported
      */
     public Formatter(String fileName, String csn, Locale l)
         throws FileNotFoundException, UnsupportedEncodingException
     {
-        init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), csn)),
-             l);
+        this(verifyCharsetName(csn),
+             l,
+             new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), csn)));
     }
 
     /**
      * Constructs a new formatter with the specified file.
      *

@@ -2055,12 +2083,12 @@
      *          regular file and a new regular file of that name cannot be
      *          created, or if some other error occurs while opening or
      *          creating the file
      */
     public Formatter(File file) throws FileNotFoundException {
-        init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
-             Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT),
+             new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))));
     }
 
     /**
      * Constructs a new formatter with the specified file and charset.
      *

@@ -2131,12 +2159,13 @@
      *          If the named charset is not supported
      */
     public Formatter(File file, String csn, Locale l)
         throws FileNotFoundException, UnsupportedEncodingException
     {
-        init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), csn)),
-             l);
+        this(verifyCharsetName(csn),
+             l,
+             new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), csn)));
     }
 
     /**
      * Constructs a new formatter with the specified print stream.
      *

@@ -2149,13 +2178,12 @@
      *
      * @param  ps
      *         The stream to use as the destination of this formatter.
      */
     public Formatter(PrintStream ps) {
-        if (ps == null)
-            throw new NullPointerException();
-        init((Appendable)ps, Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT),
+             (Appendable)Objects.nonNull(ps));
     }
 
     /**
      * Constructs a new formatter with the specified output stream.
      *

@@ -2169,12 +2197,12 @@
      * @param  os
      *         The output stream to use as the destination of this formatter.
      *         The output will be buffered.
      */
     public Formatter(OutputStream os) {
-        init(new BufferedWriter(new OutputStreamWriter(os)),
-             Locale.getDefault(Locale.Category.FORMAT));
+        this(Locale.getDefault(Locale.Category.FORMAT),
+             new BufferedWriter(new OutputStreamWriter(os)));
     }
 
     /**
      * Constructs a new formatter with the specified output stream and
      * charset.

@@ -2220,17 +2248,19 @@
      *          If the named charset is not supported
      */
     public Formatter(OutputStream os, String csn, Locale l)
         throws UnsupportedEncodingException
     {
-        init(new BufferedWriter(new OutputStreamWriter(os, csn)), l);
+        this(l, new BufferedWriter(new OutputStreamWriter(os, csn)));
     }
 
-    private void setZero() {
+    private static final char getZero(Locale l) {
         if ((l != null) && !l.equals(Locale.US)) {
             DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
-            zero = dfs.getZeroDigit();
+            return dfs.getZeroDigit();
+        } else {
+            return '0';
         }
     }
 
     /**
      * Returns the locale set by the construction of this formatter.