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<MyEnum> 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<MyEnum> 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 }
|