src/share/classes/java/io/PrintStream.java
Print this page
@@ -25,12 +25,13 @@
package java.io;
import java.util.Formatter;
import java.util.Locale;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
-
/**
* A <code>PrintStream</code> adds functionality to another output stream,
* namely the ability to print representations of various data values
* conveniently. Two other features are provided as well. Unlike other output
* streams, a <code>PrintStream</code> never throws an
@@ -54,11 +55,11 @@
public class PrintStream extends FilterOutputStream
implements Appendable, Closeable
{
- private boolean autoFlush = false;
+ private final boolean autoFlush;
private boolean trouble = false;
private Formatter formatter;
/**
* Track both the text- and character-output streams, so that their buffers
@@ -66,43 +67,77 @@
*/
private BufferedWriter textOut;
private OutputStreamWriter charOut;
/**
- * Creates a new print stream. This stream will not flush automatically.
- *
- * @param out The output stream to which values and objects will be
- * printed
- *
- * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
+ * nonNull is explicitly delcared here so as not to create an extra
+ * dependency on java.util.Objects.nonNull. PrintStream is loaded
+ * early during system initialization.
*/
- public PrintStream(OutputStream out) {
- this(out, false);
+ private static <T> T nonNull(T obj, String message) {
+ if (obj == null)
+ throw new NullPointerException(message);
+ return obj;
}
- /* Initialization is factored into a private constructor (note the swapped
- * parameters so that this one isn't confused with the public one) and a
- * separate init method so that the following two public constructors can
- * share code. We use a separate init method so that the constructor that
- * takes an encoding will throw an NPE for a null stream before it throws
- * an UnsupportedEncodingException for an unsupported encoding.
+ /**
+ * Returns the given charset name if it is supported.
+ * @throws NullPointerException is csn is null
+ * @throws UnsupportedEncodingException if the charset is not supported
*/
+ private static String verifyCharsetName(String csn)
+ throws UnsupportedEncodingException {
+ nonNull(csn, "charsetName");
+ try {
+ if (Charset.isSupported(csn))
+ return csn;
+ } catch (IllegalCharsetNameException unused) {
+ /* swallow this exception since UnsupportedEncodingException
+ * will be thrown */
+ }
+ throw new UnsupportedEncodingException(csn);
+ }
- private PrintStream(boolean autoFlush, OutputStream out)
- {
+ /* Private constructors */
+ private PrintStream(boolean autoFlush, OutputStream out) {
super(out);
- if (out == null)
- throw new NullPointerException("Null output stream");
this.autoFlush = autoFlush;
+ this.charOut = new OutputStreamWriter(this);
+ this.textOut = new BufferedWriter(charOut);
}
- private void init(OutputStreamWriter osw) {
- this.charOut = osw;
- this.textOut = new BufferedWriter(osw);
+ private PrintStream(boolean autoFlush, OutputStream out, String csn)
+ throws UnsupportedEncodingException {
+ super(out);
+ this.autoFlush = autoFlush;
+ this.charOut = new OutputStreamWriter(this, csn);
+ this.textOut = new BufferedWriter(charOut);
}
+ /* Variant of the private constructor so that the given charset name
+ * can be verified before evaluating the OutputStream argument. Used
+ * by constructors creating a FileOutputStream that also take a
+ * charset name.
+ */
+ private PrintStream(boolean autoFlush, String csn, OutputStream out)
+ throws UnsupportedEncodingException {
+ this(autoFlush, out, csn);
+ }
+
/**
+ * Creates a new print stream. This stream will not flush automatically.
+ *
+ * @param out The output stream to which values and objects will be
+ * printed
+ *
+ * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
+ */
+ public PrintStream(OutputStream out) {
+ this(out, false);
+ }
+
+ /**
* Creates a new print stream.
*
* @param out The output stream to which values and objects will be
* printed
* @param autoFlush A boolean; if true, the output buffer will be flushed
@@ -111,12 +146,11 @@
* character or byte (<code>'\n'</code>) is written
*
* @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
*/
public PrintStream(OutputStream out, boolean autoFlush) {
- this(autoFlush, out);
- init(new OutputStreamWriter(this));
+ this(autoFlush, nonNull(out, "Null output stream"));
}
/**
* Creates a new print stream.
*
@@ -136,12 +170,16 @@
* @since 1.4
*/
public PrintStream(OutputStream out, boolean autoFlush, String encoding)
throws UnsupportedEncodingException
{
- this(autoFlush, out);
- init(new OutputStreamWriter(this, encoding));
+ /* this(boolean,OutputStream,String) is invoked so that the
+ * OutputStream argument can be validated before the charset name.
+ */
+ this(autoFlush,
+ nonNull(out, "Null output stream"),
+ verifyCharsetName(encoding));
}
/**
* Creates a new print stream, without automatic line flushing, with the
* specified file name. This convenience constructor creates
@@ -169,11 +207,10 @@
*
* @since 1.5
*/
public PrintStream(String fileName) throws FileNotFoundException {
this(false, new FileOutputStream(fileName));
- init(new OutputStreamWriter(this));
}
/**
* Creates a new print stream, without automatic line flushing, with the
* specified file name and charset. This convenience constructor creates
@@ -208,12 +245,14 @@
* @since 1.5
*/
public PrintStream(String fileName, String csn)
throws FileNotFoundException, UnsupportedEncodingException
{
- this(false, new FileOutputStream(fileName));
- init(new OutputStreamWriter(this, csn));
+ /* this(boolean,String,OutputStream) is invoked so that the
+ * charset name can be verified before creating an output
+ * stream to the file. */
+ this(false, verifyCharsetName(csn), new FileOutputStream(fileName));
}
/**
* Creates a new print stream, without automatic line flushing, with the
* specified file. This convenience constructor creates the necessary
@@ -241,11 +280,10 @@
*
* @since 1.5
*/
public PrintStream(File file) throws FileNotFoundException {
this(false, new FileOutputStream(file));
- init(new OutputStreamWriter(this));
}
/**
* Creates a new print stream, without automatic line flushing, with the
* specified file and charset. This convenience constructor creates
@@ -280,12 +318,14 @@
* @since 1.5
*/
public PrintStream(File file, String csn)
throws FileNotFoundException, UnsupportedEncodingException
{
- this(false, new FileOutputStream(file));
- init(new OutputStreamWriter(this, csn));
+ /* this(boolean,String,OutputStream) is invoked so that the
+ * charset name can be verified before creating an output
+ * stream to the file. */
+ this(false, verifyCharsetName(csn), new FileOutputStream(file));
}
/** Check to make sure that the stream has not been closed */
private void ensureOpen() throws IOException {
if (out == null)