Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8283527

Update java.nio buffers to use sealed classes

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P4
    • Resolution: Approved
    • Fix Version/s: 19
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      Buffer classes have package-scope constructors so sealing them should not cause any problems.
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      Change the java.nio.Buffer hierarchy to be sealed.

      Problem

      Buffers are not sealed which it would be appropriate for them to be as they are a closed abstraction.

      Solution

      In the java.nio.Buffer class tree, convert the subclassed buffer classes to sealed and the non-subclassed classes to final.

      Specification

      --- a/src/java.base/share/classes/java/nio/Buffer.java
      +++ b/src/java.base/share/classes/java/nio/Buffer.java
      @@ -189,11 +189,13 @@
        * @author Mark Reinhold
        * @author JSR-51 Expert Group
        * @since 1.4
        */
      
      -public abstract class Buffer {
      +public abstract sealed class Buffer
      +    permits ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer,
      +        LongBuffer, ShortBuffer {
           // Cached unsafe-access object
           static final Unsafe UNSAFE = Unsafe.getUnsafe();
      
           static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
      
      --- a/src/java.base/share/classes/java/nio/ByteBufferAs-X-Buffer.java.template
      +++ b/src/java.base/share/classes/java/nio/ByteBufferAs-X-Buffer.java.template
      @@ -29,12 +29,20 @@
      
       import java.util.Objects;
       import jdk.internal.access.foreign.MemorySegmentProxy;
       import jdk.internal.misc.Unsafe;
      
      +#if[rw]
      +sealed
      +#else[rw]
      +final
      +#end[rw]
       class ByteBufferAs$Type$Buffer$RW$$BO$                  // package-private
           extends {#if[ro]?ByteBufferAs}$Type$Buffer{#if[ro]?$BO$}
      +#if[rw]
      +    permits ByteBufferAs$Type$BufferR$BO$
      +#end[rw]
       {
      
       #if[rw]
      
           protected final ByteBuffer bb;
      
      --- a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template
      +++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template
      @@ -35,17 +35,25 @@
       import jdk.internal.misc.VM;
       import jdk.internal.ref.Cleaner;
       import sun.nio.ch.DirectBuffer;
      
      
      +#if[rw]
      +sealed
      +#else[rw]
      +final
      +#end[rw]
       class Direct$Type$Buffer$RW$$BO$
       #if[rw]
           extends {#if[byte]?Mapped$Type$Buffer:$Type$Buffer}
       #else[rw]
           extends Direct$Type$Buffer$BO$
       #end[rw]
           implements DirectBuffer
      +#if[rw]
      +    permits Direct$Type$BufferR$BO$
      +#end[rw]
       {
      
       #if[rw]
      
           // Cached unaligned-access capability
      
      --- a/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template
      +++ b/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template
      @@ -38,12 +38,20 @@
        * read/write class, overriding the mutation methods to throw a {@link
        * ReadOnlyBufferException} and overriding the view-buffer methods to return an
        * instance of this class rather than of the superclass.
       #end[rw]
        */
      +#if[rw]
      +sealed
      +#else[rw]
      +final
      +#end[rw]
       class Heap$Type$Buffer$RW$
           extends {#if[ro]?Heap}$Type$Buffer
      +#if[rw]
      +    permits Heap$Type$BufferR
      +#end[rw]
       {
       #if[rw]
           // Cached array base offset
           private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
      
      --- a/src/java.base/share/classes/java/nio/MappedByteBuffer.java
      +++ b/src/java.base/share/classes/java/nio/MappedByteBuffer.java
      @@ -68,12 +68,13 @@
        * @author Mark Reinhold
        * @author JSR-51 Expert Group
        * @since 1.4
        */
      
      -public abstract class MappedByteBuffer
      +public abstract sealed class MappedByteBuffer
           extends ByteBuffer
      +    permits DirectByteBuffer
       {
      
           // This is a little bit backwards: By rights MappedByteBuffer should be a
           // subclass of DirectByteBuffer, but to keep the spec clear and simple, and
           // for optimization purposes, it's easier to do it the other way around.
      --- a/src/java.base/share/classes/java/nio/StringCharBuffer.java
      
      +++ b/src/java.base/share/classes/java/nio/StringCharBuffer.java
      @@ -27,11 +27,11 @@
      
       import java.util.Objects;
      
       // ## If the sequence is a string, use reflection to share its array
      
      -class StringCharBuffer                                  // package-private
      +final class StringCharBuffer                                  // package-private
           extends CharBuffer
       {
           CharSequence str;
      
           StringCharBuffer(CharSequence s, int start, int end) { // package-private
      
      --- a/src/java.base/share/classes/java/nio/X-Buffer.java.template
      +++ b/src/java.base/share/classes/java/nio/X-Buffer.java.template
      @@ -262,13 +262,23 @@
        * @author Mark Reinhold
        * @author JSR-51 Expert Group
        * @since 1.4
        */
      
      -public abstract class $Type$Buffer
      +public abstract sealed class $Type$Buffer
           extends Buffer
           implements Comparable<$Type$Buffer>{#if[char]?, Appendable, CharSequence, Readable}
      +    permits
      +#if[byte]
      +    Heap$Type$Buffer, MappedByteBuffer
      +#else[byte]
      +#if[char]
      +    StringCharBuffer,
      +#end[char]
      +    Heap$Type$Buffer, Direct$Type$BufferS, Direct$Type$BufferU,
      +    ByteBufferAs$Type$BufferB, ByteBufferAs$Type$BufferL
      +#end[byte]
       {
           // Cached array base offset
           private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
      
           // These fields are declared here rather than in Heap-X-Buffer in order to

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              bpb Brian Burkhalter
              Reporter:
              darcy Joe Darcy
              Reviewed By:
              Alan Bateman
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: