73 * Java Collections Framework</a>. |
73 * Java Collections Framework</a>. |
74 * |
74 * |
75 * @author Josh Bloch |
75 * @author Josh Bloch |
76 * @since 1.5 |
76 * @since 1.5 |
77 * @see EnumMap |
77 * @see EnumMap |
78 * @serial exclude |
|
79 */ |
78 */ |
80 @SuppressWarnings("serial") // No serialVersionUID due to usage of |
79 @SuppressWarnings("serial") // No serialVersionUID due to usage of |
81 // serial proxy pattern |
80 // serial proxy pattern |
82 public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E> |
81 public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E> |
83 implements Cloneable, java.io.Serializable |
82 implements Cloneable, java.io.Serializable |
84 { |
83 { |
85 /** |
84 /** |
86 * The class of all the elements of this set. |
85 * The class of all the elements of this set. |
87 */ |
86 */ |
88 final Class<E> elementType; |
87 final transient Class<E> elementType; |
89 |
88 |
90 /** |
89 /** |
91 * All of the values comprising T. (Cached for performance.) |
90 * All of the values comprising E. (Cached for performance.) |
92 */ |
91 */ |
93 final Enum<?>[] universe; |
92 final transient Enum<?>[] universe; |
94 |
93 |
95 EnumSet(Class<E>elementType, Enum<?>[] universe) { |
94 EnumSet(Class<E>elementType, Enum<?>[] universe) { |
96 this.elementType = elementType; |
95 this.elementType = elementType; |
97 this.universe = universe; |
96 this.universe = universe; |
98 } |
97 } |
414 * to ensure that the existence of a particular implementation type is |
413 * to ensure that the existence of a particular implementation type is |
415 * an implementation detail. |
414 * an implementation detail. |
416 * |
415 * |
417 * @serial include |
416 * @serial include |
418 */ |
417 */ |
419 private static class SerializationProxy <E extends Enum<E>> |
418 private static class SerializationProxy<E extends Enum<E>> |
420 implements java.io.Serializable |
419 implements java.io.Serializable |
421 { |
420 { |
422 |
421 |
423 private static final Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0]; |
422 private static final Enum<?>[] ZERO_LENGTH_ENUM_ARRAY = new Enum<?>[0]; |
424 |
423 |
439 SerializationProxy(EnumSet<E> set) { |
438 SerializationProxy(EnumSet<E> set) { |
440 elementType = set.elementType; |
439 elementType = set.elementType; |
441 elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY); |
440 elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY); |
442 } |
441 } |
443 |
442 |
444 // instead of cast to E, we should perhaps use elementType.cast() |
443 /** |
445 // to avoid injection of forged stream, but it will slow the implementation |
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 */ |
446 @SuppressWarnings("unchecked") |
450 @SuppressWarnings("unchecked") |
447 private Object readResolve() { |
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 |
448 EnumSet<E> result = EnumSet.noneOf(elementType); |
455 EnumSet<E> result = EnumSet.noneOf(elementType); |
449 for (Enum<?> e : elements) |
456 for (Enum<?> e : elements) |
450 result.add((E)e); |
457 result.add((E)e); |
451 return result; |
458 return result; |
452 } |
459 } |
453 |
460 |
454 private static final long serialVersionUID = 362491234563181265L; |
461 private static final long serialVersionUID = 362491234563181265L; |
455 } |
462 } |
456 |
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 */ |
457 Object writeReplace() { |
473 Object writeReplace() { |
458 return new SerializationProxy<>(this); |
474 return new SerializationProxy<>(this); |
459 } |
475 } |
460 |
476 |
461 // readObject method for the serialization proxy pattern |
477 /** |
462 // See Effective Java, Second Ed., Item 78. |
478 * @param s the stream |
463 private void readObject(java.io.ObjectInputStream stream) |
479 * @throws java.io.InvalidObjectException always |
|
480 */ |
|
481 private void readObject(java.io.ObjectInputStream s) |
464 throws java.io.InvalidObjectException { |
482 throws java.io.InvalidObjectException { |
465 throw new java.io.InvalidObjectException("Proxy required"); |
483 throw new java.io.InvalidObjectException("Proxy required"); |
466 } |
484 } |
467 } |
485 } |