CSR :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
Summary ------- FileInputStream and FileOutputStream and subclasses should have more flexibility to implement the closing of FileDescriptors and release other resources when the streams are unreferenced. Requiring use of finalization in all cases has a negative performance impact. Problem ------- The use of finalization by FIS/FOS to close file descriptors adds a significant overhead to garbage collection and reference processing of finalizable references. The specification of FileInputStream and FileOutputStream finalize methods requires the `close` method to be called when "there are no more references to it". As written implies, but does not mandate that `finalize` calls `close` though that is the current implementation. A clarification can enable a more efficient implementation. Also, the deprecation of the `finalize` methods should include `forRemoval = true` to give adequate notice of future removal of the `finalize` method. Solution -------- The specifications of FileInputStream and FileOutputStream are changed to require the calling of `close` when "there are no more references to it" only in the case where it would affect a subclass that has overridden either 'finalize' or 'close'. It is also explicit that `finalize` does not call close directly. In other cases, the release of resources is implementation specific. This conditional use of finalization allows the implementation flexibility to use finalization (but not necessarily the `finalize` method) to call `close` in cases where it may affect subclass behavior. Compatibility with current behavior is maintained except for the case where `finalize` is called directly, which is not usually the case. 12/5/2017: Update to simplify the condition under which the `close` method is called to depend only on the `close` method being overridden. The `finalize` method is not longer included in the condition. Specification ------------- ***java.io.FileInputStream*** Class javadoc: ``` + * @apiNote + * To release resources used by this stream {@linkplain #close} should be called + * directly or by try-with-resources. Subclasses are responsible for the cleanup + * of resources acquired by the subclass. + * Subclasses that override {@link #finalize} in order to perform cleanup + * should be modified to use alternative cleanup mechanisms such as + * {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. + * + * @implSpec + * If this FileInputStream has been subclassed and the {@linkplain #close} + * method has been overridden, the {@linkplain #close} method will be + * called when the FileInputStream is unreachable. + * Otherwise, it is implementation specific how the resource cleanup described in + * {@linkplain #close} is performed. ``` Method finalize(): ``` /** * Ensures that the {@linkplain #close} method of this file input stream is * called when there are no more references to it. + * The {@link #finalize} method does not call {@linkplain #close} directly. * + * @implSpec + * If this FileInputStream has been subclassed and the {@linkplain #close} + * method has been overridden, the {@linkplain #close} method will be + * called when the FileInputStream is unreachable. + * Otherwise, it is implementation specific how the resource cleanup described in + * {@linkplain #close} is performed. + * + * @apiNote + * To release resources used by this stream {@linkplain #close} should be called + * directly or by try-with-resources. + * + * @deprecated The {@code finalize} method has been deprecated and will be removed. * Subclasses that override {@code finalize} in order to perform cleanup * should be modified to use alternative cleanup mechanisms and * to remove the overriding {@code finalize} method. @@ -425,15 +460,39 @@ * @exception IOException if an I/O error occurs. * @see java.io.FileInputStream#close() */ + @Deprecated(since="9", forRemoval = true) {...} ``` ***java.io.FileOutputStream*** Class javadoc: ``` + * @apiNote + * To release resources used by this stream {@linkplain #close} should be called + * directly or by try-with-resources. Subclasses are responsible for the cleanup + * of resources acquired by the subclass. + * Subclasses that override {@link #finalize} in order to perform cleanup + * should be modified to use alternative cleanup mechanisms such as + * {@link java.lang.ref.Cleaner} and remove the overriding {@code finalize} method. + * + * @implSpec + * If this FileOutputStream has been subclassed and the {@linkplain #close} + * method has been overridden, the {@linkplain #close} method will be + * called when the FileOutputStream is unreachable. + * Otherwise, it is implementation specific how the resource cleanup described in + * {@linkplain #close} is performed. ``` Method finalize(): ``` /** * Cleans up the connection to the file, and ensures that the * {@linkplain #close} method of this file output stream is * called when there are no more references to this stream. + * The {@link #finalize} method does not call {@linkplain #close} directly. + * + * @implSpec + * If this FileOutputStream has been subclassed and the {@linkplain #close} + * method has been overridden, the {@linkplain #close} method will be + * called when the FileOutputStream is unreachable. + * Otherwise, it is implementation specific how the resource cleanup described in + * {@linkplain #close} is performed. + * + * @apiNote + * To release resources used by this stream {@linkplain #close} should be called + * directly or by try-with-resources. + * + * @deprecated The {@code finalize} method has been deprecated and will be removed. + * Subclasses that override {@code finalize} in order to perform cleanup + * should be modified to use alternative cleanup mechanisms and + * to remove the overriding {@code finalize} method. + * When overriding the {@code finalize} method, its implementation must explicitly + * ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}. + * See the specification for {@link Object#finalize()} for further + * information about migration options. * * @exception IOException if an I/O error occurs. * @see java.io.FileInputStream#close() */ + @Deprecated(since="9", forRemoval = true) protected void finalize() throws IOException {...} ```
|