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

Make ConcurrentHashMap.CollectionView a sealed hierarchy

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 19
    • core-libs
    • None
    • source
    • minimal
    • Hide
      Since the `CollectionView` class was already package private, we don't expect any sub-classes other than the one identified in this CSR to exist.
      The `KeySetView` which is being marked `final` in this CSR, only has a package private constructor, so we don't expect any sub-classes for this class to exist.
      Show
      Since the `CollectionView` class was already package private, we don't expect any sub-classes other than the one identified in this CSR to exist. The `KeySetView` which is being marked `final` in this CSR, only has a package private constructor, so we don't expect any sub-classes for this class to exist.
    • Java API
    • SE

      Summary

      Update java.util.concurrent.CollectionView to be a sealed class and java.util.concurrent.CollectionView$KeySetView to be final class.

      Problem

      java.util.concurrent.CollectionView is a package private class with a package private constructor. It currently has 3 subclasses - EntrySetView, KeySetView and ValuesView. The EntrySetView and ValuesView are both final classes. The KeySetView is a public class, but it only has a package private constructor. Making the CollectionView a sealed class with only these 3 subclasses are permitted with more clearly convey its usage/design intent.

      Solution

      CollectionView will be marked as sealed and KeySetView will be marked as final. Although the KeySetView is a public class, it only has a package private constructor and as such cannot be subclasses outside of this package. No subclasses of this class currently exist in this package. Additionally, the javadoc of this class already states "This class cannot be directly instantiated", so changing this to final shouldn't impact any other classes.

      This entire class hierarchy of CollectionView and its subclasses implement the java.io.Serializable interface. Updating the KeySetView to be final changes the auto-generated serial version id of the class, but since the KeySetView already has a custom serialVersionUID defined for this class, changing this class to final will not impact the serial version id or backward compatibility (in context of serialization/de-serialization) of this class.

      Specification

      --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java
      +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java
      @@ -4416,8 +4416,8 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
           /**
            * Base class for views.
            */
      -    abstract static class CollectionView<K,V,E>
      -        implements Collection<E>, java.io.Serializable {
      +    abstract static sealed class CollectionView<K,V,E>
      +        implements Collection<E>, java.io.Serializable permits EntrySetView, KeySetView, ValuesView {
               private static final long serialVersionUID = 7249069246763182397L;
               final ConcurrentHashMap<K,V> map;
               CollectionView(ConcurrentHashMap<K,V> map)  { this.map = map; }
      @@ -4589,7 +4589,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
            *
            * @since 1.8
            */
      -    public static class KeySetView<K,V> extends CollectionView<K,V,K>
      +    public static final class KeySetView<K,V> extends CollectionView<K,V,K>
               implements Set<K>, java.io.Serializable {
               private static final long serialVersionUID = 7249069246763182397L;
               @SuppressWarnings("serial") // Conditionally serializable
      

            jpai Jaikiran Pai
            smarks Stuart Marks
            Stuart Marks
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: