< prev index next >

src/java.base/share/classes/java/util/EnumSet.java

Print this page
8192935: Fix EnumSet's SerializationProxy javadoc
Reviewed-by: smarks, rriggs


  58  * the set should be "wrapped" using the {@link Collections#synchronizedSet}
  59  * method.  This is best done at creation time, to prevent accidental
  60  * unsynchronized access:
  61  *
  62  * <pre>
  63  * Set&lt;MyEnum&gt; s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));
  64  * </pre>
  65  *
  66  * <p>Implementation note: All basic operations execute in constant time.
  67  * They are likely (though not guaranteed) to be much faster than their
  68  * {@link HashSet} counterparts.  Even bulk operations execute in
  69  * constant time if their argument is also an enum set.
  70  *
  71  * <p>This class is a member of the
  72  * <a href="{@docRoot}/java/util/package-summary.html#CollectionsFramework">
  73  * Java Collections Framework</a>.
  74  *
  75  * @author Josh Bloch
  76  * @since 1.5
  77  * @see EnumMap
  78  * @serial exclude
  79  */
  80 @SuppressWarnings("serial") // No serialVersionUID due to usage of
  81                             // serial proxy pattern
  82 public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
  83     implements Cloneable, java.io.Serializable
  84 {
  85     /**
  86      * The class of all the elements of this set.
  87      */
  88     final Class<E> elementType;
  89 
  90     /**
  91      * All of the values comprising T.  (Cached for performance.)
  92      */
  93     final Enum<?>[] universe;
  94 
  95     EnumSet(Class<E>elementType, Enum<?>[] universe) {
  96         this.elementType = elementType;
  97         this.universe    = universe;
  98     }
  99 
 100     /**
 101      * Creates an empty enum set with the specified element type.
 102      *
 103      * @param <E> The class of the elements in the set
 104      * @param elementType the class object of the element type for this enum
 105      *     set
 106      * @return An empty enum set of the specified type.
 107      * @throws NullPointerException if {@code elementType} is null
 108      */
 109     public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
 110         Enum<?>[] universe = getUniverse(elementType);
 111         if (universe == null)
 112             throw new ClassCastException(elementType + " not an enum");
 113 


 399     }
 400 
 401     /**
 402      * Returns all of the values comprising E.
 403      * The result is uncloned, cached, and shared by all callers.
 404      */
 405     private static <E extends Enum<E>> E[] getUniverse(Class<E> elementType) {
 406         return SharedSecrets.getJavaLangAccess()
 407                                         .getEnumConstantsShared(elementType);
 408     }
 409 
 410     /**
 411      * This class is used to serialize all EnumSet instances, regardless of
 412      * implementation type.  It captures their "logical contents" and they
 413      * are reconstructed using public static factories.  This is necessary
 414      * to ensure that the existence of a particular implementation type is
 415      * an implementation detail.
 416      *
 417      * @serial include
 418      */
 419     private static class SerializationProxy <E extends Enum<E>>
 420         implements java.io.Serializable
 421     {
 422 
 423         private static final Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0];
 424 
 425         /**
 426          * The element type of this enum set.
 427          *
 428          * @serial
 429          */
 430         private final Class<E> elementType;
 431 
 432         /**
 433          * The elements contained in this enum set.
 434          *
 435          * @serial
 436          */
 437         private final Enum<?>[] elements;
 438 
 439         SerializationProxy(EnumSet<E> set) {
 440             elementType = set.elementType;
 441             elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
 442         }
 443 
 444         // instead of cast to E, we should perhaps use elementType.cast()
 445         // to avoid injection of forged stream, but it will slow the implementation





 446         @SuppressWarnings("unchecked")
 447         private Object readResolve() {



 448             EnumSet<E> result = EnumSet.noneOf(elementType);
 449             for (Enum<?> e : elements)
 450                 result.add((E)e);
 451             return result;
 452         }
 453 
 454         private static final long serialVersionUID = 362491234563181265L;
 455     }
 456 









 457     Object writeReplace() {
 458         return new SerializationProxy<>(this);
 459     }
 460 
 461     // readObject method for the serialization proxy pattern
 462     // See Effective Java, Second Ed., Item 78.
 463     private void readObject(java.io.ObjectInputStream stream)


 464         throws java.io.InvalidObjectException {
 465         throw new java.io.InvalidObjectException("Proxy required");
 466     }
 467 }


  58  * the set should be "wrapped" using the {@link Collections#synchronizedSet}
  59  * method.  This is best done at creation time, to prevent accidental
  60  * unsynchronized access:
  61  *
  62  * <pre>
  63  * Set&lt;MyEnum&gt; s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));
  64  * </pre>
  65  *
  66  * <p>Implementation note: All basic operations execute in constant time.
  67  * They are likely (though not guaranteed) to be much faster than their
  68  * {@link HashSet} counterparts.  Even bulk operations execute in
  69  * constant time if their argument is also an enum set.
  70  *
  71  * <p>This class is a member of the
  72  * <a href="{@docRoot}/java/util/package-summary.html#CollectionsFramework">
  73  * Java Collections Framework</a>.
  74  *
  75  * @author Josh Bloch
  76  * @since 1.5
  77  * @see EnumMap

  78  */
  79 @SuppressWarnings("serial") // No serialVersionUID due to usage of
  80                             // serial proxy pattern
  81 public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
  82     implements Cloneable, java.io.Serializable
  83 {
  84     /**
  85      * The class of all the elements of this set.
  86      */
  87     final transient Class<E> elementType;
  88 
  89     /**
  90      * All of the values comprising E.  (Cached for performance.)
  91      */
  92     final transient Enum<?>[] universe;
  93 
  94     EnumSet(Class<E>elementType, Enum<?>[] universe) {
  95         this.elementType = elementType;
  96         this.universe    = universe;
  97     }
  98 
  99     /**
 100      * Creates an empty enum set with the specified element type.
 101      *
 102      * @param <E> The class of the elements in the set
 103      * @param elementType the class object of the element type for this enum
 104      *     set
 105      * @return An empty enum set of the specified type.
 106      * @throws NullPointerException if {@code elementType} is null
 107      */
 108     public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
 109         Enum<?>[] universe = getUniverse(elementType);
 110         if (universe == null)
 111             throw new ClassCastException(elementType + " not an enum");
 112 


 398     }
 399 
 400     /**
 401      * Returns all of the values comprising E.
 402      * The result is uncloned, cached, and shared by all callers.
 403      */
 404     private static <E extends Enum<E>> E[] getUniverse(Class<E> elementType) {
 405         return SharedSecrets.getJavaLangAccess()
 406                                         .getEnumConstantsShared(elementType);
 407     }
 408 
 409     /**
 410      * This class is used to serialize all EnumSet instances, regardless of
 411      * implementation type.  It captures their "logical contents" and they
 412      * are reconstructed using public static factories.  This is necessary
 413      * to ensure that the existence of a particular implementation type is
 414      * an implementation detail.
 415      *
 416      * @serial include
 417      */
 418     private static class SerializationProxy<E extends Enum<E>>
 419         implements java.io.Serializable
 420     {
 421 
 422         private static final Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0];
 423 
 424         /**
 425          * The element type of this enum set.
 426          *
 427          * @serial
 428          */
 429         private final Class<E> elementType;
 430 
 431         /**
 432          * The elements contained in this enum set.
 433          *
 434          * @serial
 435          */
 436         private final Enum<?>[] elements;
 437 
 438         SerializationProxy(EnumSet<E> set) {
 439             elementType = set.elementType;
 440             elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
 441         }
 442 
 443         /**
 444          * Returns an {@code EnumSet} object with initial state
 445          * held by this proxy.
 446          *
 447          * @return a {@code EnumSet} object with initial state
 448          * held by this proxy
 449          */
 450         @SuppressWarnings("unchecked")
 451         private Object readResolve() {
 452             // instead of cast to E, we should perhaps use elementType.cast()
 453             // to avoid injection of forged stream, but it will slow the
 454             // implementation
 455             EnumSet<E> result = EnumSet.noneOf(elementType);
 456             for (Enum<?> e : elements)
 457                 result.add((E)e);
 458             return result;
 459         }
 460 
 461         private static final long serialVersionUID = 362491234563181265L;
 462     }
 463 
 464     /**
 465      * Returns a
 466      * <a href="../../serialized-form.html#java.util.EnumSet.SerializationProxy">
 467      * SerializationProxy</a>
 468      * representing the state of this instance.
 469      *
 470      * @return a {@link SerializationProxy}
 471      * representing the state of this instance
 472      */
 473     Object writeReplace() {
 474         return new SerializationProxy<>(this);
 475     }
 476 
 477     /**
 478      * @param s the stream
 479      * @throws java.io.InvalidObjectException always
 480      */
 481     private void readObject(java.io.ObjectInputStream s)
 482         throws java.io.InvalidObjectException {
 483         throw new java.io.InvalidObjectException("Proxy required");
 484     }
 485 }
< prev index next >