Some subclasses of java.io.(Input/Output)Stream behave as proxies/decorators,
i.e. wrap other streams offering some additional service. Not all of them check
the stream they wrap on null though.
In many cases it doesn't make any sense, and defers the failure until actual
data operations (read/write/skip, etc.) are performed. Sometimes a null
wrapped stream silently violates implicit invariants. That leads to a confusing
behaviour. For example, if you try to read something from
new BufferedInputStream(null)
you'll get "java.io.IOException: Stream closed" which is strange, since you
haven't explicitly closed it.
Here are the list (maybe not comprehensive) of constructors that behaves this
way:
InputStream:
public java.io.BufferedInputStream(java.io.InputStream)
public java.io.PushbackInputStream(java.io.InputStream)
public java.io.LineNumberInputStream(java.io.InputStream)
public java.io.DataInputStream(java.io.InputStream)
public java.security.DigestInputStream(java.io.InputStream,java.security.MessageDigest)
public java.util.zip.CheckedInputStream(java.io.InputStream,java.util.zip.Checksum)
OutputStream:
public java.io.BufferedOutputStream(java.io.OutputStream)
public java.io.DataOutputStream(java.io.OutputStream)
public java.security.DigestOutputStream(java.io.OutputStream,java.security.MessageDigest)
public java.util.zip.CheckedOutputStream(java.io.OutputStream,java.util.zip.Checksum)
The following classes go even further, they keep a straight face until the very
last moment:
1. new BufferedOutputStream(null, x) with any byte[] x where x.length > 0
You can write to it, but you won't get NPE until you flush() the guy, or a
number of bytes written exceeds the size of the buffer.
2. Some of BufferedOutputStream subclasses:
sun.security.krb5.internal.util.KrbDataOutputStream,
sun.security.krb5.internal.ktab.KeyTabOutputStream,
sun.net.TelnetOutputStream,
sun.security.krb5.internal.ccache.CCacheOutputStream
com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream,
sun.net.httpserver.ChunkedOutputStream
3. sun.rmi.transport.proxy.HttpOutputStream
Will use wrapped stream only on close!
i.e. wrap other streams offering some additional service. Not all of them check
the stream they wrap on null though.
In many cases it doesn't make any sense, and defers the failure until actual
data operations (read/write/skip, etc.) are performed. Sometimes a null
wrapped stream silently violates implicit invariants. That leads to a confusing
behaviour. For example, if you try to read something from
new BufferedInputStream(null)
you'll get "java.io.IOException: Stream closed" which is strange, since you
haven't explicitly closed it.
Here are the list (maybe not comprehensive) of constructors that behaves this
way:
InputStream:
public java.io.BufferedInputStream(java.io.InputStream)
public java.io.PushbackInputStream(java.io.InputStream)
public java.io.LineNumberInputStream(java.io.InputStream)
public java.io.DataInputStream(java.io.InputStream)
public java.security.DigestInputStream(java.io.InputStream,java.security.MessageDigest)
public java.util.zip.CheckedInputStream(java.io.InputStream,java.util.zip.Checksum)
OutputStream:
public java.io.BufferedOutputStream(java.io.OutputStream)
public java.io.DataOutputStream(java.io.OutputStream)
public java.security.DigestOutputStream(java.io.OutputStream,java.security.MessageDigest)
public java.util.zip.CheckedOutputStream(java.io.OutputStream,java.util.zip.Checksum)
The following classes go even further, they keep a straight face until the very
last moment:
1. new BufferedOutputStream(null, x) with any byte[] x where x.length > 0
You can write to it, but you won't get NPE until you flush() the guy, or a
number of bytes written exceeds the size of the buffer.
2. Some of BufferedOutputStream subclasses:
sun.security.krb5.internal.util.KrbDataOutputStream,
sun.security.krb5.internal.ktab.KeyTabOutputStream,
sun.net.TelnetOutputStream,
sun.security.krb5.internal.ccache.CCacheOutputStream
com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream,
sun.net.httpserver.ChunkedOutputStream
3. sun.rmi.transport.proxy.HttpOutputStream
Will use wrapped stream only on close!
- relates to
-
JDK-8228392 Backout incorrect change done by JDK-8067801
-
- Resolved
-
-
JDK-8228204 Fix for JDK-8067801 breaks java/io/NegativeInitSize.java
-
- Resolved
-
-
JDK-8228338 tools/pack200/TimeStamp.java fails with NullPointerException
-
- Resolved
-
- links to